cv::circle 的奇怪行为

Weird behaviour of cv::circle

我正在尝试使用 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);

既然你说图像在 cv::circle 调用之前看起来很好,那么 GetColorFrame() returns 数据可能会在循环 运行 时发生变化。 尝试:

  • a GetColorFrame().clone() 看看这是否解决了问题,或者
  • 改变 GetColorFrame 的工作方式。

Kinect SDK 仅提供读取 4 通道图像(即 RGBA)的功能,但是,cv::circle 函数似乎以一种奇怪的方式对这类图像崩溃。通过调用 cvtImage 删除 alpha 通道,我可以解决问题。