0
votes

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?

2
Whats src.type()? Why do you access samples as "floats" and src as "Vec3b", when they both have the same type? - Jan Rüegg

2 Answers

0
votes

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

enter image description here

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

enter image description here

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

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.