Biju
Biju

Reputation: 71

How to divide an M×N image into non-overlapping blocks of [3,3]?

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?

Upvotes: 1

Views: 7312

Answers (2)

Royi
Royi

Reputation: 4953

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

Sum of Absolute differences between images in Matlab

Upvotes: 0

Rody Oldenhuis
Rody Oldenhuis

Reputation: 38032

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

Upvotes: 1

Related Questions