1

I need to create A 16X16 window to scan over an entire image in matlab and record the position and grey level value of pixel with largest grey level in window.

Can anyone guide me on how to do this? Cant find any help on creating windows on images.

Thanks

user1853871
  • 249
  • 5
  • 21
  • So, the position vector would be of a length same as the number of pixels right? Because it's for every pixel? – Divakar Apr 02 '14 at 16:28

4 Answers4

2

Just for fun, here is another way of achieving this: store the intensity and the position of the maximum in your window as the real and imaginary parts of a complex number. You can then use the nfilter function to perform the moving filtering:

fun = @(x) complex(double(max(x(:))),double(find(x==max(x(:)), 1, 'first')));
B = nlfilter(YourImage,[16 16],fun);

You can then access the maximum and its position from the complex map. Here is an example of the results when applied to one of the images given in this post:

Max intensity in the neighborhood (imagesc(real(B))):

enter image description here

Position of the maximum (imagesc(img(B))):

enter image description here

Community
  • 1
  • 1
Cape Code
  • 3,584
  • 3
  • 24
  • 45
1

You could do it like this:

% img = [matrix representing your image]

N = 16;

window = repmat(struct, ceil(size(img, 1) / N), ceil(size(img, 2) / N));
for row = 1:N:size(img, 1)
    for col = 1:N:size(img, 2)
        r = (row - 1) / N + 1;
        c = (col - 1) / N + 1;

        imgWindow = img(row:min(end,row+N-1), col:min(end,col+N-1));
        largest = max(imgWindow(:));
        [rLarg, cLarg] = find(imgWindow == largest, 1, 'first');

        window(r, c).largest = largest;
        window(r, c).row = rLarg + row - 1;
        window(r, c).col = cLarg + col - 1;
    end
end

You'll have a matrix called window where window(r,c) contains information about window (r,c), with the fields:

  • window(r,c).largest: gray level of the largest pixel
  • window(r,c).row, window(r,c).col: position of the largest pixel on the original image
Rafael Monteiro
  • 4,509
  • 1
  • 16
  • 28
  • You're welcome. One thing I forgot to mention is this: if there are two or more largest pixels (all with the same gray level), the code will pick the first one for row/col coordinates, using sequencial indexing. If you want the coordinates of them all, just change the **find** line to `find(window == largest);` and now row/col will be vectors with the coordinates of all largest pixels in each window. – Rafael Monteiro Apr 02 '14 at 16:50
  • thanks, couild you just explain to me what r = (row - 1) / N + 1; c = (col - 1) / N + 1; does? – user1853871 Apr 02 '14 at 16:56
  • Sure. Suppose your image is 48x48 pixels. Therefore, there are 3x3 windows. Variables **row** and **col** in both for's will assume the values 1, 17 and 33, which are the starting position of each window. That two lines you asked will translate those to 1, 2 and 3, respectively, which are the indexes of each window. – Rafael Monteiro Apr 02 '14 at 17:08
  • thanks. I am now confused about the next step in my alogrithm... IF pixels surrounding the largest pixel are as bright as the largest pixel grey level value AND outer pixels are darker than the largest pixel grey level value THEN largest pixel position is the center pixel of an ROI. Can you explain to me how to start by getting the pixels surrounding the largest pixel? – user1853871 Apr 03 '14 at 09:52
  • Glad I could help. I'm new on Stackoverflow, but I think you should ask this by creating another question, because it's a new problem. – Rafael Monteiro Apr 03 '14 at 14:58
  • ok :) http://stackoverflow.com/questions/22862387/matlab-find-surrounding-pixels-and-outer-pixels – user1853871 Apr 04 '14 at 12:08
1

Old school for-Loop method -

%%// Outputs that you are interested in are - img, x1 and y1
img = rgb2gray(input_image); %%// Gray level values
x1 = zeros(size(img)); %%// Row values for the maximum pixel in the 16x16 window
y1 = zeros(size(img)); %%// Column values for the maximum pixel in the 16x16 window
for k1= 1:size(img,1)-15
    for k2= 1:size(img,2)-15
        img1 = img(k1:k1+15,k2:k2+15);        
        [val,ind1] = max(img1(:));
        img(k1+8,k2+8)=val; %%// Store the max grey value into the image
        [x1(k1,k2),y1(k1,k2)] = ind2sub([16 16],ind1);
    end
end

Edit 1: For calculating mean across this sliding window, use this -

window_size = 16; %%// Edit this to your window size

wsz = window_size-1;
mp = round(window_size/2);

%%// Outputs that you are interested in are - img, x1 and y1
img = rgb2gray(input_image); %%// Gray level values
x1 = zeros(size(img)); %%// Row values for the maximum pixel in the 16x16 window
y1 = zeros(size(img)); %%// Column values for the maximum pixel in the 16x16 window

img1 = img;
for k1= 1:size(img,1)-wsz
    for k2= 1:size(img,2)-wsz
        window_data = img(k1:k1+wsz,k2:k2+wsz);        
        val = round(mean(window_data(:)));
        img1(k1+mp,k2+mp)=val; %%// Store the mean grey value into the image
    end
end

figure,imshow(img1)

Edit 2:

img1 = Z;
for k1= 1:size(Z,1)-wsz
    for k2= 1:size(Z,2)-wsz
        window_data = Z(k1:k1+wsz,k2:k2+wsz);        
        val = mean(window_data(:))
        if (val~=0)
            keyboard;
            error('Look, there is a non-zero mean value!');
        end
       % img1(k1+mp,k2+mp)=val; %%// Store the mean grey value into the image
        display(val);
    end
end
Divakar
  • 218,885
  • 19
  • 262
  • 358
0

The key step you need is to extract a sub image the given scanning window (i.e. rectangle area). If the scanning winow, say roi is in format [x, y, width, height], you can simply call imcrop:

subImage = imcrop(Image, roi);

Then you can find the max gray level in the sub image, like this

[value, location] = max(subImage(:));

Of course, you need to update the scanning window i.e. roi in order to scan over the whole image.

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174