C++ cv::circle的怪异行为

C++ cv::circle的怪异行为,c++,visual-studio,opencv,kinect,C++,Visual Studio,Opencv,Kinect,我试图用OpenCV 3在从Kinect v2传感器获取的图像上绘制两个圆圈 cv::circle似乎有一个奇怪的bug,或者我不明白函数是如何工作的。让我们看一些代码: if(kinectDataManager.IsColorStreamEnabled()) { cv::Mat colorFrameMat = kinectDataManager.GetFrame().GetColorFrame() cv::imshow("Color", colorFrameMat) }

我试图用OpenCV 3在从Kinect v2传感器获取的图像上绘制两个圆圈

cv::circle
似乎有一个奇怪的bug,或者我不明白函数是如何工作的。让我们看一些代码:

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)
}

由于您说在调用
cv::circle
之前图像看起来很好,因此
GetColorFrame()
可能返回循环运行时更改的数据。 尝试:

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

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

你为什么不按照
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行的最后一个位置结束。这是一个好主意!然而,问题仍然存在,即使是在第一帧。
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);