I recently had to perform a block average on an image to reduce its size for processing in MATLAB and learned about a useful function called `blkproc`

or `blockproc`

(in the newer versions) in the Image Processing Toolbox. Block averaging is a process by which you average non-overlapping blocks of an image, which becomes a single pixel in the block averaged image. The standard image resize functions use a filter to resize the image and does not allow the blocks to be non-overlapping.

MATLAB's `blkproc`

or `blockproc`

functions facilitate this by making it easy for you to specify a function to be applied to blocks in the image. If you have an image `img`

and want to do a M x N block average (i.e. the pixels of the resultant image are the average of M x N blocks in the original), you can use:

img = blkproc(img, [M N], 'mean2');

In newer versions of MATLAB, `blockproc`

is preferred and is used this way:

fun = @(block_struct) mean2(block_struct.data); img = blockproc(img, [M N], 'fun');

`mean2`

is an Image Processing Toolbox function that takes a 2D array and returns the mean of all values. The distinction between `blkproc`

usage and `blockproc`

usage is that with `blockproc`

, the function that it expects in place of `mean2`

takes a *block struct* structure instead of an array. Hence, we need to define a new inline function `fun`

which provides the right interface by wrapping the `mean2`

function.

What `blkproc`

/ `blockproc`

does is divides the image up into M x N blocks and feeds each one to `mean2`

and then takes the result and puts it into a single pixel in the new image.

You can replace `mean2`

with other functions that take an M x N array and returns a M' x N' array (where M' and N' are arbitrary numbers; for `mean2`

this is always 1 x 1) and the result will be constructed by tiling the M' x N' arrays in the order that the M x N blocks occur in the original image. The figure below shows what happens:

The original image is 20 x 20 pixels. Setting M = 4 and N = 4 and using `mean2`

(which outputs M' = 1 and N' = 1), the final image is 5 x 5 pixels.

When the image cannot be divided up into an integer number of M x N blocks, you will get border effects as the `blkproc`

function pads images out by zeros. The newer version `blockproc`

allows you to specify how you want to treat the partial blocks, either process them as is or pad them with zeros, with the 'PadPartialBlocks' parameter. See the MATLAB documentation for details.

The MATLAB documentation does not indicate the actual order of processing of the blocks (i.e. the actual sequence by which the blocks are processed). If the `blkproc`

or `blockproc`

implementation is parallel or multithreaded, there will not be any guaranteed order at all.

I believe that the `blkproc`

function is single threaded on a single core computer, so the order of processing should be simple. To find out, I used the following test function, which does nothing except print the value of each image block pased into it. When I use this function with `blkproc`

, I will use a block size of 1 x 1 so it will only print one value each time the function is executed.

function a = testblkproc(imblock) disp(sprintf('%g', imblock)) a = imblock;

I then constructed a matrix of values that I can easily interpret:

>> a = [1 4 7; 2 5 8; 3 6 9] a = 1 4 7 2 5 8 3 6 9

Finally, I ran `blkproc`

with my test function `testblkproc`

using a block size of 1 x 1. This makes it output the order in which the 1 x 1 blocks are procesed:

>> blkproc(a,[1 1],'testblkproc'); 1 4 7 2 5 8 3 6 9

According to this test, `blkproc`

processes entire rows first before moving onto the next row. I should re-iterate that this is only applicable to the `blkproc`

function running on a single core computer.