C++ 中 cv::Rectangle 的问题
Posted
技术标签:
【中文标题】C++ 中 cv::Rectangle 的问题【英文标题】:Problems with cv::Rectangle in C++ 【发布时间】:2017-10-18 10:17:30 【问题描述】:在 cv :: mat 中绘制矩形时遇到问题。我正在 Unity 和 C++ 之间进行通信以生成 android 应用程序。
我使用统一的 webcamtexture 相机,并使用 PInvoke 方法将信息发送到 C++。一旦在 C++ 代码中,我想绘制一个矩形,但我在图像中得到了多个(见图),我真的不明白为什么。希望大家帮我附上C++和C#代码。
C#
void Update()
//texto.text = texto.text + " / "+ testo().ToString();
imgData = null;
imgData = new byte[width * height * 3];
resultado = null;
resultado = new byte[width * height * 3];
color = webcam.GetPixels32();
int bytesPerPixel = 3;
const int indexR = 0;
const int indexG = 1;
const int indexB = 2;
for (var i = 0; i < color.Length; i++)
imgData[(i * bytesPerPixel) + indexR] = color[i].r;
imgData[(i * bytesPerPixel) + indexG] = color[i].g;
imgData[(i * bytesPerPixel) + indexB] = color[i].b;
color = null;
ProcessFrame(imgData, resultado, 0, 0, 0,0, nuevo);
nuevo = false;
textura2 = new Texture2D(width, height, TextureFormat.RGB24, false);
textura2.LoadRawTextureData(resultado);
textura2.Apply();
renderer.material.mainTexture = textura2;
textura2 = null;
Resources.UnloadUnusedAssets();
C++
void ProcessFrame(unsigned char* arr, unsigned char* resu,int posx, int posy, int poswidth, int posheight,bool nuevo)
Mat dst;//dst image
trueRect.x = 150;
trueRect.y = 150;
trueRect.width = 100;
trueRect.height = 100;
wi = poswidth;
he = posheight;
mal = 20;
dst = Mat(tamWid,tamHeid,CV_8UC3, arr);
rectangle(dst, Point(50,50), Point(100,100), cv::Scalar(0, 255, 255));
copy(dst.datastart, dst.dataend, resu);
【问题讨论】:
我不能肯定地说,但我的猜测是你已经用行移动了列,即 OpenCV 存储图像数据列和 Unity (OpenGL) 行(或其他方式)。您可以调试此 C++ 代码并使用 ImageWatch 插件检查矩阵吗?或者简单地使用cv::imwrite
保存 dst。此外,您应该先复制 dst 然后再绘制它。至于现在你改变原始图像并复制它,所以两者都有矩形。
抱歉,我不确定你在告诉我什么。我在之前的函数中传递了图像大小的信息,它的分辨率为 640x480。我不明白你想用边缘说什么,更不用说你如何解决它了。关于 Debug,我不能使用,因为我正在统一使用共享库来创建 Android 应用程序。
@R2RT opencv 是行专业的。问题是dst = Mat(tamWid,tamHeid,CV_8UC3, arr);
它是构造函数中的行、列,所以它应该是dst = Mat(tamHeid,tamWid,CV_8UC3, arr);
然后您还必须检查数据是按列还是按行,如果是按列,则需要将其保留为在垫子之前和转置
@api55 是的,我认为你是对的。你应该让它成为一个答案。 Urko,试试Mat(tamHeid,tamWid,CV_8UC3, arr);
成功了,谢谢大家解决方案:Mat(tamHeid,tamWid,CV_8UC3, arr);
【参考方案1】:
为了完整起见,我将发布答案。
问题出在一行
dst = Mat(tamWid,tamHeid,CV_8UC3, arr);
constructor of Mat 将前两个参数行和列作为前两个参数,在您的情况下是列和行。
应该是这样的:
dst = Mat(tamHeid,tamWid,CV_8UC3, arr);
其他注意事项
正如我在 cmets 中所说,您应该注意某些可能的错误来源,因为 OpenCV 和 Unity 中的约定不同。其中之一是您的 2D 坐标系的原点。在 OpenCV 中位于左上角,在 Unity 中,或者至少 GetPixels32
函数位于图像的左下角。
另一个可能的问题是色彩空间。 OpenCV 在加载、保存和其他功能时需要 BGR 图像,而在其他框架中它们使用 32 位的 RGB 或 RGBA。
【讨论】:
以上是关于C++ 中 cv::Rectangle 的问题的主要内容,如果未能解决你的问题,请参考以下文章
cv2.rectangle() 调用重载方法,虽然我给出了其他参数
为啥 cv2.rectangle 有时会返回 np.ndarray,而有时会返回 cv2.UMat
利用cv2.rectangle()绘制矩形框(python)