cv::circle 的奇怪行为
Posted
技术标签:
【中文标题】cv::circle 的奇怪行为【英文标题】:Weird behaviour of cv::circle 【发布时间】:2015-12-01 10:49:11 【问题描述】:我正在尝试使用 OpenCV 3 在从 Kinect v2 传感器获得的图像上绘制几个圆圈。
cv::circle
似乎有一个奇怪的错误,或者我不明白该函数是如何工作的。让我们看一些代码:
if(kinectDataManager.IsColorStreamEnabled())
cv::Mat colorFrameMat = kinectDataManager.GetFrame().GetColorFrame()
cv::imshow("Color", colorFrameMat)
这段代码运行良好,使用 ImageWatch Visual Studio 插件检查 OpenCV 图像,我可以看到 colorFrameMat
矩阵没有损坏。
让我们再看一些代码:
if(kinectDataManager.IsColorStreamEnabled())
cv::Mat colorFrameMat = kinectDataManager.GetFrame().GetColorFrame()
int radius = 2;
int y = 1068;
for (int x = 0; x < 1920; ++x)
cv::circle(colorFrameMat, cv::Point(x,y), radius, cv::Scalar(255, 0, 0), -1, CV_AA);
cv::imshow("Color", colorFrameMat)
循环执行完成后,ImageWatch 插件显示图像的最后一行丢失。奇怪的是,程序仍然执行。但是,对于y
的不同值,程序会由于访问冲突而崩溃,例如对于y = 1067
,程序会因x = 1917
而崩溃。对于y = 1069
,它在x = 988
处崩溃。
有人知道问题可能是什么吗?
编辑: ImageWatch 插件当然会显示最后一行丢失了,因为圆圈是从左到右在这些位置绘制的,请原谅错误!
编辑2:
存储一帧并读入后,具有相同代码的cv::circle
方法工作正常:
cv::Mat test = cv::imread("test.jpg", CV_LOAD_IMAGE_COLOR);
cv::namedWindow("test", CV_WINDOW_NORMAL);
int radius = 10;
int y = 1067;
for (int x = 0; x < 1920; ++x)
cv::circle(test, cv::Point(x, y), radius, cv::Scalar(0, 0, 255, 255), -1, CV_AA);
cv::imshow("test", test);
cv::waitKey(0);
【问题讨论】:
你为什么不按照Mat.rows
或Mat.cols
(或Mat.size().width
/Math.size().height
)工作??
我不明白这与我的问题有什么关系。我使用 Kinect SDK 函数获取图像帧的宽度和高度。在 imshow
调用之前,Mat.rows
和 Mat.cols
分别是 1080
和 1920
。
因为没有任何日志、崩溃日志或常量,所以有点难以帮助
我完全可以理解,但是我不知道我可以提供什么样的日志。在cv::circle
调用之前,图像看起来非常好。在循环的某个地方,最后一行丢失了......
你的图片占用的内存是固定的。如果您假设错误的图像宽度或高度,您假设的像素线从一个非常错误的位置开始。这就是为什么您的代码在不同的 x 坐标处崩溃的原因。拍摄 4 行 512 列的图像。现在,如果您要求第一行将从内存位置 0 开始,第二行将从 512 开始,依此类推。但是,如果您假设图像有 1024 列,则您希望第二行从位置 1024 开始。如果您现在尝试访问该行中不存在的 1024 像素,您将在第 4 行的最后一个位置结束。
【参考方案1】:
Kinect SDK 仅提供读取 4 通道图像(即 RGBA)的功能,但是,cv::circle
函数似乎以一种奇怪的方式崩溃此类图像。通过调用 cvtImage
删除 alpha 通道,我可以解决问题。
【讨论】:
【参考方案2】:由于您说图像在cv::circle
调用之前看起来不错,因此GetColorFrame()
返回的数据可能会在循环运行时发生变化。
试试:
GetColorFrame().clone()
看看这是否能解决问题,或者
改变GetColorFrame
的工作方式。
【讨论】:
这是个好主意!但是,即使是第一帧,问题仍然存在。以上是关于cv::circle 的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章