Reputation: 47
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
Reputation: 41765
You're doing two things wrong:
uchar
), so you need to access it with .at<uchar>(...)
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:
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);
}
}
The new OpenCV name is IMREAD_GRAYSCALE
:
Mat1b dst = imread("path_to_image", IMREAD_GRAYSCALE);
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
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
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