使用opencv在内存位置出现异常

Posted

技术标签:

【中文标题】使用opencv在内存位置出现异常【英文标题】:Exception at memory location with opencv 【发布时间】:2018-11-26 10:49:12 【问题描述】:

我是新的 opencv c++ 开发人员。我应用了 SLIC 超像素,所以我有 Mat:labels 包含每个像素的 ID,我在图像上应用 SPLIT 以获得绿色通道,然后我希望更改 ID=150 的特定像素的值(每个pixel =! of 150 必须转换为黑色像素)。调试后我得到了这个错误和这个window:

在 0x00007FFB63A0A388 处引发异常:Microsoft C++ 异常:内存位置 0x0000001496AFE290 处的 cv::Exception。 0x00007FFB63A0A388 处未处理的异常:Microsoft C++ 异常:内存位置 0x0000001496AFE290 处的 cv::Exception。

这是我的代码

   int main()


    Mat labels;
    Mat RGB[3], HSV[3],S_HSV,image3;
    vector<double> STD, generale_mean;
    Mat image, Red, Green, Blue, image2,mask,Gray;
    int region_number;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    image = imread("D:\\mémoire\\eye.png", CV_LOAD_IMAGE_COLOR);

    //applying the superpixel 

    Ptr<cv::ximgproc::SuperpixelSLIC> slic = cv::ximgproc::createSuperpixelSLIC(image, 100,50, 0.01);
    slic->iterate(10);
    if (true)
        slic->enforceLabelConnectivity(50);

    slic->getLabelContourMask(mask, true);
    image.setTo((0, 0, 255), mask);
    slic->getLabels(labels);
    region_number = slic->getNumberOfSuperpixels();

    cv::cvtColor(image, image, CV_BGR2RGB);

    cv::cvtColor(image, Gray,CV_RGB2GRAY);

    split(image, RGB);

    Red.push_back(RGB[0]);
    Green.push_back(RGB[1]);
    Blue.push_back(RGB[2]);

        int f = 150;
        Mat Green1 = Green.clone();
        int Y =0;

        for (int j = 0; j < Green1.rows; j++) 
            for (int i = 0; i < Green1.cols; i++) 

                double N = labels.at<double>(Point(i, j));
                if (N =! f) 

                    Green1.at<double>(Point(i, j)) = 00000;

            
        

        cv::imshow("green", Green1);        

    waitKey(0);         // Wait for a keystroke in the window
    return 0;

【问题讨论】:

你调试过这个吗?这还不足以让我们为您提供更多帮助。 我会更新我的帖子并放上所有代码 抛出的异常是什么?错误信息基本上只是说 OpenCV 抛出了异常,但并没有显示 opencv 异常的详细信息。例如,调用堆栈真的很有帮助。 如何显示异常?! 错误在这一行 Green1.at&lt;double&gt;(Point(i, j)) = 00000; first is an uchar not a double, 你可以不用像这样的点 Green1.at&lt;uchar&gt;(j,i) = 0; 注意在接收行、列与接收 x 的点的比较,y 【参考方案1】:

图片的类型有问题。在 OpenCV 中加载图像时使用:

image = imread(filename, CV_LOAD_IMAGE_COLOR);

它将是 CV8UC3 类型的图像。这意味着它将有 3 个通道(C3 部分),并且每个通道的每个像素值都是 8 位的无符号整数类型。在 C++ 中,您可以使用 uchar 。那么当你使用 at 函数时,你需要使用一种可以正确保存信息的类型……在这个例子中就是 uchar。在您的代码中,您有:

Green1.at<double>(Point(i, j)) = 00000;

应该是:

Green1.at<uchar>(j,i) = 0;

请注意,Point(i,j) 也不需要,可以替换为 j,i

.at&lt;type&gt;(row, column) 函数或多或少等同于做:

Mat test;
type* data = reinterpret_cast<type*>(test.data);
data[row][column];

你也有问题:

double N = labels.at<double>(Point(i, j));

但标签是由

分配的
slic->getLabels(labels);

它给出了一个 CV_32SC1 类型的垫子 -> 这意味着,1 个通道和 32 位有符号整数,或者在 C++ 中,int。

那么这应该是:

int N = labels.at<int>(j,i);

最后:

这个

Red.push_back(RGB[0]);
Green.push_back(RGB[1]);
Blue.push_back(RGB[2]);

应该是:

Red = RGB[0];
Green = RGB[1];
Blue = RGB[2];

【讨论】:

以上是关于使用opencv在内存位置出现异常的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenCV (2.4.5) 时出现内存异常

OpenCV cvCanny 内存异常

关于在Opencv中使用Releaseimread时候出现,错误

c# emgu/opencv 使用抛出异常 - 试图读取或写入受保护的内存

C ++中的openCV Mat访问冲突

写入文件时OpenCV未处理的异常