Avoid partial blocks in block processing with blockproc

2 views (last 30 days)
If you block process an image using blockproc and the desired block size does not divide evenly into your image size, it seems that the output includes a 'partial' block at the end. Below is an example. Is there any way to avoid this, so only 'full' blocks are returned?
I = imread('ngc6543a.jpg'); % Read in an example image of size 650x600x3
xBlockSize = 90; yBlockSize = 90; % Desired block size doesn't divide evenly into image size
% Get the row and column counters, so we can see what happens to them
[nRow, nCol, ~] = size(I);
x = 1:nCol; y = 1:nRow; % Vector of counters
[X,Y] = meshgrid(x,y); % Matrix of counters, which we can block process
% The next 2 lines say to take the mean value of each block
% (Could take the median, max, etc instead by substituting "median" or "max" for "mean")
str = '@(block_struct) mean(block_struct.data,[1 2], ''omitnan'')';
functionHandle = str2func(str); % Get the function handle to the anonymous function
% Block process the image
INew = blockproc(I, [yBlockSize xBlockSize], functionHandle); % Size 8x7x3
% However 650/90 = 7.2 and 600/90 = 6.7, so there are only 7x6x3 full blocks
% Block process the row and column counters to see what is going on
YCenter = blockproc(Y, [yBlockSize xBlockSize], functionHandle); % Find the mean counter value for each block
XCenter = blockproc(X, [yBlockSize xBlockSize], functionHandle);
xCenter = XCenter(1,:); % Vector of block-averaged column counters
dX = diff(xCenter) % Take the counter difference to see how many pixels included in each block
% dX=[90 90 90 90 90 75], so last block is 'partial'
yCenter = YCenter(:,1); % Vector of block-averaged row counters
dY = diff(yCenter) % How many pixels are included in each block
% dY=[90 90 90 90 90 90 55], so last block is 'partial'
% Could check if dX(end) < median(dX) to discard the last partial block, but is there another way?

Accepted Answer

Image Analyst
Image Analyst on 4 Jan 2019
You can compute how many blocks your image will be and crop off any "leftover" pixels with imcrop() or simple indexing. For example, blocks are 8 and your image is 68 by 71 pixels.
blockSize = 8;
[rows, columns, numColors] = size(grayImage);
numBlocksAcross = floor(columns / blockSize);
numPixelsAcross = numBlocksAcross * blockSize;
numBlocksTall = floor(rows / blockSize);
numPixelsTall = numBlocksTall * blockSize;
grayImage = grayImage(1:numPixelsTall, 1 : numPixelsAcross, :); % Crop.

More Answers (0)

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!