leo liu
leo liu

Reputation: 47

OpenCV Error: Assertion failed / when visit the pixel of mat

I'm using OpenCV to try to calculate the sum of each pixel from a grayscale picture.

cv::Mat dst;
dst = imread("dst.png", CV_LOAD_IMAGE_GRAYSCALE);
for (i = 0; i < dst.cols; i++)
{
    for (j = 0; j < dst.rows; j++)
    {
        dstSum += dst.at<Vec3b>(i, j)[0];
    }
}

And then the error comes:

OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3) - 1))*4) & 15) == elemSize1()) in cv::Mat::at,

I googled this error message, it looks like I visit the pixel out of the matrix.

But I do have the i < dst.cols and j < dst.rows to make sure that situtation won't happen, right?

So what's the possible reason for this error... Can anybody help me on this?

Upvotes: 0

Views: 987

Answers (3)

Miki
Miki

Reputation: 41765

You're doing two things wrong:

  1. You image is grayscale (uchar), so you need to access it with .at<uchar>(...)
  2. You are accessing the image as (col, row), while the OpenCV (and any matrix-related) convention is (row, col). You can also use mnemonics in your iteration: r and c for row and col respectively.

    for(int r=0; r<dst.rows; r++) {
        for( c=0; c<dst.cols; c++){
            dstSum += dst.at<uchar>(r, c);
        }   
    }
    

You can also improve your code a little:

  1. You can use Mat1b and access it like at(i,j)

    Mat1b dst = imread(...);
    for(int r=0; r<dst.rows; r++) {
        for( c=0; c<dst.cols; c++){
            dstSum += dst(r, c);
        }   
    }
    
  2. The new OpenCV name is IMREAD_GRAYSCALE:

    Mat1b dst = imread("path_to_image", IMREAD_GRAYSCALE);
    
  3. You can use cv::sum to sum up all the pixels. The resulting improved code will be:

    Mat1b dst = imread("path_to_image", IMREAD_GRAYSCALE);
    int dstSum = sum(dst)[0]; // take only first channel
    

Upvotes: 0

Axel B.
Axel B.

Reputation: 131

As you can see here, OpenCV uses a (row,col) indexation.

Try

for(i=0;i<dst.rows;i++){
    for(j=0;j<dst.cols;j++){
        dstSum += dst.at<uchar>(i, j);
    }
}

instead of your (col, row) indexation.

Upvotes: 0

kh&#244;i nguyễn
kh&#244;i nguyễn

Reputation: 628

dst = imread("dst.png", CV_LOAD_IMAGE_GRAYSCALE);

You read the dst as a gray scale 8-bit image, that means each pixel have 1 channel, and 8-bit depth for this channel. So inside the loop should be

dstSum += dst.at<uchar>(i, j);

You can read more details here.

Upvotes: 1

Related Questions