Eugene
Eugene

Reputation: 11280

Loop through an image with a mask in openCV

I need to collect some data from an image. Looping should be done with a mask.

For example, I have a simple cross mask:

  1  
1 1 1
  1

And I need to know the sum of gray value of every point of Image.

I can use simple loops, like this:

// looping except first and last
int nr = image.rows-1;
int nc = image.cols-1;

    for (int j=1; j<nr; j++) { // for all rows

    const uchar* previous = image.ptr<const uchar>(j-1); // previous row
    const uchar* current = image.ptr<const uchar>(j); // current row
    const uchar* next = image.ptr<const uchar>(j+1); // next row

    for (int i=1; i<nc; i++) {
        sum = previos[i] + current[i] + current[i-1] 
                          + current[i+1] + next[i];

    }
}

But I think I do this wrong. May be I should use something like cv::Mat kernel()?

I need mask to be a parameter, so I can use any kind of mask.

Is there a ready function for looping an image with a mask? ( There is filter2D function, but I don't need to make changes with an images, only some calculations with pixels ).

Upvotes: 2

Views: 3179

Answers (1)

moooeeeep
moooeeeep

Reputation: 32542

If you want the sum for each pixel, isn't that exactly what filter2d() does? You compute the sums for each pixel, and then use these sums to go on with SUSAN: (untested code)

cv::Mat img;
// TODO: load img
cv::Mat kernel = cv::Mat::ones(3,3,CV_8U);
// TODO: set some elements to zero you don't like
cv::Mat sums = img.clone();
cv::filter2d(img, sums, -1, kernel);
// TODO: use sums for further computation 

What happens at the edges of your image depends on the border extrapolation type you specify for filter2d. From the docs:

Another common feature of the functions and classes described in this section is that, unlike simple arithmetic functions, they need to extrapolate values of some non-existing pixels. For example, if you want to smooth an image using a Gaussian 3 \times 3 filter, then, when processing the left-most pixels in each row, you need pixels to the left of them, that is, outside of the image. You can let these pixels be the same as the left-most image pixels (“replicated border” extrapolation method), or assume that all the non-existing pixels are zeros (“constant border” extrapolation method), and so on. OpenCV enables you to specify the extrapolation method. For details, see the function borderInterpolate() and discussion of the borderType parameter in the section and various functions below.

/*
 Various border types, image boundaries are denoted with '|'

 * BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
 * BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
 * BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
 * BORDER_WRAP:          cdefgh|abcdefgh|abcdefg
 * BORDER_CONSTANT:      iiiiii|abcdefgh|iiiiiii  with some specified 'i'
 */

Upvotes: 2

Related Questions