简体   繁体   English

CV :: Mat导致运行时错误-OpenCV错误-断言失败

[英]CV::Mat causing runtime error - OpenCV Error - Assertion failed

I am working on a image processing project and i am encountering a crash in the system. 我在一个图像处理项目上工作,遇到系统崩溃。 This is the error that keeps popping: 这是不断弹出的错误:

OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)si ze.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channel s()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3 ) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file d:\\libs\\opencv-249\\build\\i nclude\\opencv2\\core\\mat.hpp, line 537 OpenCV错误:断言失败(尺寸<= 2 && data &&(unsigned)i0 <(unsigned)si ze.p [0] &&(unsigned)(i1 * DataType <_Tp> :: channels)<(unsigned)(size。 p [1] * channel s())&&(((((sizeof(size_t)<< 28)| 0x8442211)>>(((DataType <_Tp> :: depth)&&((1 << 3 -1))) * 4)和15)== elemSize1())在cv :: Mat :: at中,文件d:\\ libs \\ opencv-249 \\ build \\ i nclude \\ opencv2 \\ core \\ mat.hpp,第537行

I was able to find that the following bit of code is making the problem 我发现以下代码导致了问题

samples = (src.size(), src.type());
imshow ("source" , src);
for( int y = 0; y < src.rows; y++ )
for( int x = 0; x < src.cols; x++ )
  for( int z = 0; z < 3; z++){

      samples.at<float>((y + (x*src.rows)), z) = src.at<Vec3b>(y,x)[z];}

samples is a Mat object that is declared in the header file of this class. samples是在此类头文件中声明的Mat对象。

I also referred to this link but even though the error is the same the code that is causing the crash is not the same as mine. 我也提到了此链接,但即使错误相同,导致崩溃的代码也与我的不同。 But the awkward thing is that this exact piece of code works fine within another function, but when i try to include the same code within a method that belongs to a class it is making this error. 但是尴尬的是,这段确切的代码在另一个函数中可以正常工作,但是当我尝试在属于类的方法中包含相同的代码时,就会出现此错误。

I am clueless. 我无能为力。 Can anyone help me out? 谁能帮我吗?

In the call samples.at<float>((y + (x*src.rows)), z) you access the image at a point where x = z and y = (y + (x*src.rows) . 在调用samples.at<float>((y + (x*src.rows)), z)您可以在x = zy = (y + (x*src.rows)的位置访问图像。

The highest value for y you can get is (y + (x*src.rows)) = (src.rows-1 + ((src.cols-1)*src.rows)) = src.rows*src.cols-1 . 您可以获得的y的最大值是(y + (x*src.rows)) = (src.rows-1 + ((src.cols-1)*src.rows)) = src.rows*src.cols-1 This is much higher than the maximum allowed value of src.cols-1, so OpenCV throws an assertion telling you that this is out of the range of the image. 这远高于src.cols-1的最大允许值,因此OpenCV会抛出一个断言,告诉您这超出了图像范围。

I don't know why it works in one part of the code and not in another, but this is clearly an issue. 我不知道为什么它在代码的一部分而不是在代码的另一部分起作用,但这显然是一个问题。

Also, whats src.type()? 另外,src.type()是什么? Why do you access samples as "floats" and src as "Vec3b", when they both have the same type? 当它们都具有相同的类型时,为什么要以“ floats”和“ src”作为“ Vec3b”来访问样本? This seems to be very dangerous to do, as well. 这似乎也很危险。

It seems that you want samples to be a matrix with: 似乎您希望samples成为具有以下内容的矩阵:

# rows     : src.rows * src.cols
# cols     : src.channels() // it's probably 3,
type       : CV_32F (float)
# channels : 1 (single channel matrix)

You than access the rows of samples using the index of the position (r,c) in src : 然后,您将使用src中的位置(r,c)的索引访问samples的行:

int index = r * src.cols + c;

For example, if src is a 2x4 3 channel image (with random values): 例如,如果src2x4 3通道图像(具有随机值):

在此处输入图片说明

You want samples to be a 8x3 single channel float matrix: 您希望samples成为8x3单通道浮点矩阵:

在此处输入图片说明

Code: 码:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main()
{
    // Init src image
    Mat src(2, 4, CV_8UC3);
    randu(src, Scalar(0, 0, 0), Scalar(255, 255, 255));

    // Init samples image
    // # rows = src.rows * src.cols
    // # cols = src.channels()
    // type   =  CV_32FC1 (single channel float, while src type is 3 channel CV_8U)
    Mat samples(src.rows * src.cols, src.channels(), CV_32FC1);

    for (int r = 0; r < src.rows; ++r)
    {
        for (int c = 0; c < src.cols; ++c)
        {
            int index = r * src.cols + c;
            for (int channel = 0; channel < src.channels(); ++channel)
            {
                samples.at<float>(index, channel) = src.at<Vec3b>(r, c)[channel];
            }
        }
    }

    cout << "SRC: " << endl << src << endl << endl;
    cout << "SAMPLES: " << endl << samples << endl << endl;


    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM