Ask Your Question

apply a 3X3 window kernel in an image

asked 2015-12-20 23:14:40 -0500

Hossain Md Shakhawat gravatar image

updated 2015-12-20 23:41:17 -0500

berak gravatar image

I want to apply a 3X3 window kernel in an image and replace the center pixel with the minimum difference between its surrounding pixels. Anybody please provide me with some help. I am new with OpenCV. And want to apply this process on whole image.

edit retag flag offensive close merge delete


Take a look at cv::dilate and cv::erode . These can be used as maximum/minimum filters

matman gravatar imagematman ( 2015-12-22 06:35:40 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2015-12-21 10:57:27 -0500

Tetragramm gravatar image

To be clear, you want to calculate the difference between the center pixel, and the 8 surrounding pixels, pick the minimum difference, and store that?

The easiest way is to initialize a Mat the size of your image with MAX_VALUE, let's call it result.

Create different views of your image using the example cv::Mat view = image(cv::Rect(x,y,width,height));

Subtract (or absdiff, if appropriate) the two views, storing it in a temporary variable, then do result = cv::min(result, temp);

So as an example, this would be the first of 8, doing (x-1, y-1) against (x, y).

cv::Mat result(image.rows, image.cols, CV_?);
result.setTo(MAX_VALUE_OF_CV_?);//Whatever your data type is.
cv::Mat temp, center, offset;

//This is the views for this offset. Note that the size is one smaller in both x and y, because you //can't calculate the difference between (0,0) and (-1,-1).
cv::Rect centerRect = cv::Rect(1,1,image.cols-1,image.rows-1);
cv::Rect offsetRect = cv::Rect(0,0,image.cols-1,image.rows-1);

center = image(centerRect);
offset = image(offsetRect);
cv::absdiff(center, offset, temp);  //Do the actual work.

//Note then that the results are only valid for centerRect too.  
//Once you've done this for all 8, result contains what you want.
result(centerRect) = cv::min(result(centerRect), temp);
edit flag offensive delete link more


Actually I have done this using for loop and taking image an mat. But the problem is when accessing (x-1,y-1) point for x=0 and y=0. As it is out of matrix. Is there any way to test if a matrix position is out of range.

Thanks for you help. Would you please explain it more?

Hossain Md Shakhawat gravatar imageHossain Md Shakhawat ( 2015-12-22 02:29:17 -0500 )edit

Would please explain the line center = image(centerRect);

Hossain Md Shakhawat gravatar imageHossain Md Shakhawat ( 2015-12-22 07:40:24 -0500 )edit

Ah, starting simpler then. A pixel is valid if the value is 0<= X < image.cols and 0<= Y < image.rows

So, ignoring speed, loop over each pixel, then for each, go from (x-1 to x+1) and (y-1 to y+1). Then check that this new pixel is in the image, using the inequalities above. (4 total conditions ANDed together) If it isn't in the image, or if the second pixel is at (x,y), skip it. Why if it's (x,y)? Because the difference is always 0, and so your result would just be all zeros.

If it's valid, go to your result image (which should be the same size as your input and initialized to MAX_VALUE) and store the min of what's already there and the absolute difference between first and second pixel.

Do you see how this is different from convolution? Do ...(more)

Tetragramm gravatar imageTetragramm ( 2015-12-22 15:43:33 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2015-12-20 23:14:40 -0500

Seen: 314 times

Last updated: Dec 21 '15