简体   繁体   中英

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

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.

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

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 . 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.

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()? Why do you access samples as "floats" and src as "Vec3b", when they both have the same type? This seems to be very dangerous to do, as well.

It seems that you want samples to be a matrix with:

# 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 :

int index = r * src.cols + c;

For example, if src is a 2x4 3 channel image (with random values):

在此处输入图片说明

You want samples to be a 8x3 single channel float matrix:

在此处输入图片说明

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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