简体   繁体   中英

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?

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.

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.

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 

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