1

I have an M×N image that should be divided into non-overlapping blocks of [3 3]. For each block I should make the gradient vector, have the mean of them and finally normalize.

I have resized the image to a dividable dimension by [3 3] and used blockproc but when I tested like

fun = @(block_struct) mean2(block_struct.data);
A   = blockproc(im,[3 3],fun);

I saw that the block isn't applied to the whole image, but to the top left side of image.

Note: The number of blocks is not known.

[x,y]=size(im)
r=floor(x/3)
c=floor(y/3)
ext_x = mod(x,3);
ext_y = mod(y,3);
a = im(1:(end-ext_x), 1:(end-ext_y));
f= @(block_struct) gradient(block_struct.blockSize);
b=blockproc(im,[3,3],f);
imshow(b)

Any ideas?

Biju
  • 71
  • 1
  • 2
  • 8

2 Answers2

1

You do know that if you do imshow(A) the size of the image displayed will be 3 times less than that of im? That is because mean2 of course reduces each block of 3×3 to a single scalar...

Apart from the obvious, I don't see that there's anything wrong with what you're doing. I also can't reproduce what you're saying.

As a partial solution: remember that many of MATLAB's functions are just there to make life for the average user as easy as possible. They're often not terribly complex to implement, just a bit time consuming.

It's fairly trivial to cook together your own basic blockproc:

%// Some bogus data
A = reshape(1:16, 4, 4);

%// Desired blocksize
blockSize = [2 2];

%// The desired function 
fcn = @(x) mean2(gradient(x));

%// "blockproc"
m = 1;
blocks = size(A)./blockSize;
out = cell(blocks);
for jj = 1:blocks(2)
    for ii = 1:blocks(1)

        % The indices to the current block
        blockIndsX = (1:blockSize(1)) + (ii-1)*blocks(1);
        blockIndsY = (1:blockSize(2)) + (jj-1)*blocks(2);

        %// Apply the function to the current block and store the result
        out{m} = fcn( A(blockIndsX, blockIndsY, :) );

        %// the index to the next output value
        m = m + 1;
    end
end

%// Make outcomes more intuitive; if every entry is a scalar, make the result a matrix
if all(cellfun(@isscalar, out(:)))
    out = reshape([out{:}], size(out)); end
Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96
  • Thanks Rody, I just added my code above to have a look at it.It gives me a black square (as its not expected) besides that how can I count the blocks plz? – Biju Nov 20 '13 at 13:11
  • @Biju: count the blocks? What do you mean? Have you taken a look at the `blocks` variable in my code? It defines how many blocks in X and Y directions there will be... – Rody Oldenhuis Nov 20 '13 at 13:25
  • yes I have noticed already, but isn't it possible to use blockproc() itself? because i tested your code and it warns me about the index exceeds the matrix dimensions. (instead of A, I used the a variable in my code above, and I made the floor for blocks)...also it gives me m=4 for an image of 296*160 which is wrong. – Biju Nov 20 '13 at 14:05
  • @Biju: of course that is possible, but I don't know what you're doing wrong with it because I don't experience the same problems as you are. I wrote the code above so you could play around with the blocks a bit easier. It's really just there to help **you** figure out what is going wrong with the normal `blockproc`. Don't get lost on the details of my method; just try to make it work on a small image, and use it to figure out the real problem. – Rody Oldenhuis Nov 20 '13 at 16:00
0

You can use the command im2col.
You can see its usage here:

Sum of Absolute differences between images in Matlab

Community
  • 1
  • 1
Royi
  • 4,640
  • 6
  • 46
  • 64