Filter löschen
Filter löschen

Avoid partial blocks in block processing with blockproc

1 Ansicht (letzte 30 Tage)
KAE
KAE am 4 Jan. 2019
Beantwortet: Image Analyst am 4 Jan. 2019
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?

Akzeptierte Antwort

Image Analyst
Image Analyst am 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.

Weitere Antworten (0)

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by