How to divide an image into blocks in MATLAB?

Since blockproc (and the deprecated blkproc) are both functions in the Image Processing Toolbox, I thought I'd add a basic MATLAB solution that requires no additional toolboxes...

If you want to divide a matrix into submatrices, one way is to use mat2cell to break the matrix up and store each submatrix in a cell of a cell array. For your case, the syntax would look like this:

C = mat2cell(I, [128 128], [128 128]);

C is now a 2-by-2 cell array with each cell storing a 128-by-128 submatrix of I. If you want to perform an operation on each cell, you could then use the function cellfun. For example, if you wanted to take the mean of the values in each submatrix, you would do the following:

meanValues = cellfun(@(x) mean(x(:)), C);

The first argument is a function handle to an anonymous function which first reshapes each submatrix into a column vector and then takes the mean. The output is a 2-by-2 matrix of the mean values for each submatrix. If the function you pass to cellfun creates outputs of different sizes or types for each cell, then cellfun will have a problem concatenating them and will throw an error:

??? Error using ==> cellfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.

If you add ..., 'UniformOutput', false); to the end of your call to cellfun, then the output in the above case will instead be a 2-by-2 cell array containing the results of performing the operation on each submatrix.


blockproc is the new name for blkproc (which is deprecated). It can be used to apply a function to each block in an image. For example, if you wanted to divide a matrix I into 8x8 blocks and calculate the mean of each block, you would do this:

B=blockproc(I, [8 8], @(x) mean(x.data(:)));

B is then a matrix containing the means of the blocks.

Two things to note here:

  • The specifier [8 8] specifies the size of the blocks, not the number of blocks.

  • You don't get access to the blocks themselves outside of the function you pass to blockproc. If you need the blocks themselves, you have to do as Adrien suggested:

    A1=I(1:128, 1:128);
    A2=I(129:256, 1:128);
    A3=I(1:128, 129:256);
    A4=I(129:256, 129:256);
    

    Of course, in a real program, you should probably do this using a loop.


Its it better for you to make your program work for all sizes of images not just for 256*256.


[row, col]=size(your_image);
mr = round(row/2); % median of rows
mc = round(col/2); % median of columns
% Now divide your image and call each of them separately and do what ever you   want
top_left  = your_image(1:mr  , 1:mc);
top_right = your_image(1:mr  , (mc+1):col); 
bot_left  = your_image((mr+1):row , 1:mc);
bot_right = your_image((mr+1):row , (mc+1):col);
% final stage is to combining these parts again to return to its original shape 
Back_to_original = [top_left,top_right ; bot_left,bot_right]; `   

hope this will be useful for you.


If myImage is your 256x256 image, wouldn't it be

image_top_left = myImage(1:128,1:128);
image_top_right = myImage(1:128,129:256);
image_bottom_left = myImage(129:256,1:128);
image_bottom_right = myImage(129:256,129:256);

?