0
votes

I have a double image and my aim is to convert it to logical. I want to create 5x5 window and put it on each pixel in the image. Then, I calculate the average of these 25 pixels. If the center pixel value is greater then the average value, it will be 1. Otherwise 0.

How can I do that?

P.S. I don't want to do that this way:

IM[i - 2, j - 2]
IM[i - 1, j - 2]
IM[i, j - 2]
IM[i + 1, j - 2]
IM[i + 2, j - 2]
      .
      .
2

2 Answers

1
votes

Several approaches (running time is probably in decreasing order):

  1. With nlfilter:

    result = nlfilter(im, [5 5], @(x) x(3,3)>mean(x(:)));
    
  2. With blockproc:

    result = blockproc(im, [1 1], @(x) x.data(3,3)>mean(x.data(:)), ...
        'Bordersize', [2 2], 'Trimborder', 0);
    

    Note that with blockproc we need to specify blocks of size 1x1 (so that the block "moves" from pixel to pixel in each direction), border of size 2 in eacch direction around wach pixel (to get 5x5 blocks), and prevent the function result from being trimned, because the result is just 1 value.

  3. With conv2:

    result = im > conv2(im, ones(5,5)/25, 'same');
    
0
votes

If I am right, it seems like a outlier method. The code below may be what you wanted:

mask   = 0.04 * ones(5); mask(3, 3) = 0; % // mask is for average the double image
avgIm  = filter2(mask, imd); % // imd is your double image.
output = imd > avgIm;