Ask Your Question
0

Creating a sub array of a Mat throws assertion error

asked 2015-08-13 09:51:30 -0600

Hey there,

In my program, I am looping through a 2D Mat, using a rectangle with width 5 and height 1, and checking float point values in this sub array. My code goes as follow:

for (int i = 0; i < dist.rows; ++i) {  
    for (int j = 2; j < dist.cols -2; ++j) {
        search_mask = dist(Rect(i, j - 2, 5, 1).clone();
        minMaxLoc(search_mask, NULL, NULL, NULL, &local_max);
        if (local_max.x == i) {
            skeleton.at<uchar>(i, j) = 255;
        }
    }
}

My original picture has size 640*363. When the first loop reached the value i = 359, I get an assertion error:

OpenCV Error: Assertion failed (0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows) in cv:: Mat::Mat

As far as I can tell, the problem is, that when i = 359, roi.x = 359, roi. width = 5 and so roi.x + roi.width = 364, and m.cols = 363 and so 364 <= 363 is false.

My first question is, am I doing something wrong here?

My second question, why the hell would the number of rows matter when it comes to deciding if the number of columns in the sub array is not greater, than the number of columns in the original image.

Thank you for your help.

Also, sorry if I have left something important out.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2015-08-13 10:32:56 -0600

unxnut gravatar image

If you want to extract a rectangular area from dist, the recommended way is

dist.operator()(Rect(i,j-2,5,1))

So, your statement in the loop should read

search_mask = dist.operator()(Rect(i, j - 2, 5, 1)).clone();
edit flag offensive delete link more

Comments

Thank you, but unfortunately this does not solve my problem.

bkarpati gravatar imagebkarpati ( 2015-08-13 10:39:12 -0600 )edit
1

Rect should be defined with Rect(j-2,i,5,1). You are using row number in place of x.

unxnut gravatar imageunxnut ( 2015-08-13 10:50:01 -0600 )edit

You are right, now I just don't understand why they would mark the y coordinate with x and vice versa...

bkarpati gravatar imagebkarpati ( 2015-08-13 10:56:12 -0600 )edit
2

You can establish a convention to use (c,r) for (column,row) in place of (x,y) to avoid confusion.

unxnut gravatar imageunxnut ( 2015-08-13 11:14:03 -0600 )edit

What I don't understand is, that OpenCV has the (0,0) coordinate at the upper left corner, the first coordinate is for the row, the second is for the column, and the Rect function asks for an x coordinate first, then a y, so it should ask for the row first. Yet, it works only, when I provide the column first. Or am I missing out on something?

bkarpati gravatar imagebkarpati ( 2015-08-13 13:23:32 -0600 )edit

If you take your origin at the top left corner, then getting a (x,y) coordinate is exactly (cols,rows). Your x axis is always the horizontal one, and y the vertical one. Do you get it now?

StevenPuttemans gravatar imageStevenPuttemans ( 2015-08-14 04:27:15 -0600 )edit

You see, my problem is, that if you have the following code for example:

    for (int r = 0; r < image.rows; ++r) {
    for (int c = 0; c < image.cols; ++c) {
        image.at<type>(r,c) = something here;
    }
}

Then you are accessing pixels using (row, column) not (column, row).

UPDATE:

I have just done some simple drawings, which resulted in exactly what you said, the origin is at the top left corner, and coordinates can be accessed using (column, row).

Considering this, you see, why it is confusing, in my code, you can access pixels using (row, column)

bkarpati gravatar imagebkarpati ( 2015-08-14 05:43:25 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-08-13 09:51:30 -0600

Seen: 526 times

Last updated: Aug 13 '15