How to divide an image into non-overlapping blocks?

29 vues (au cours des 30 derniers jours)
Riya Augustine
Riya Augustine le 13 Fév 2017
Modifié(e) : muhamed ibrahim le 29 Mar 2024 à 22:52
For block pairing, I need to divide original block and target blocks into non-overlapping blocks.I tried with the function called blockproc(),but it is not suitable for images that i have taken.
% Divide the image up into 4 blocks.
% Let's assume we know the block size and that all blocks will be the same size.
blockSizeR = 128; % Rows in block.
blockSizeC = 128; % Columns in block.
% Figure out the size of each block.
wholeBlockRows = floor(rows / blockSizeR);
wholeBlockCols = floor(columns / blockSizeC);
% Preallocate a 3D image
image3d = zeros(wholeBlockRows, wholeBlockCols, 3);
% Now scan though, getting each block and putting it as a slice of a 3D array.
sliceNumber = 1;
for row = 1 : blockSizeR : rows
for col = 1 : blockSizeC : columns
% Let's be a little explicit here in our variables
% to make it easier to see what's going on.
% Determine starting and ending rows.
row1 = row;
row2 = row1 + blockSizeR - 1;
row2 = min(rows, row2); % Don't let it go outside the image.
% Determine starting and ending columns.
col1 = col;
col2 = col1 + blockSizeC - 1;
col2 = min(columns, col2); % Don't let it go outside the image.
% Extract out the block into a single subimage.
oneBlock = grayImage(row1:row2, col1:col2);
% Specify the location for display of the image.
subplot(2, 2, sliceNumber);
imshow(oneBlock);
% Make the caption the block number.
caption = sprintf('Block #%d of 4', sliceNumber);
title(caption, 'FontSize', fontSize);
drawnow;
% Assign this slice to the image we just extracted.
if (row2-row1+1) == blockSizeR && (col2-col1+1) == blockSizeC
% Then the block size is the tile size,
% so add a slice to our 3D image stack.
image3D(:, :, sliceNumber) = oneBlock;
else
newTileSize = [(row2-row1+1), (col2-col1+1)];
warningMessage = sprintf('Warning: this block size of %d rows and %d columns\ndoes not match
the preset block size of %d rows and %d columns.\nIt will not be added to the 3D image stack.',...
newTileSize(1), newTileSize(2), blockSizeR, blockSizeC);
uiwait(warndlg(warningMessage));
end
sliceNumber = sliceNumber + 1;
end
end
Is there any specific range for blocksizeR and blocksizeC, can I assign different sizes? if I want non overlapping blocks, how these values are connected?

Réponse acceptée

Walter Roberson
Walter Roberson le 13 Fév 2017
% Divide the image up into 4 blocks.
% Let's assume we know the block size and that all blocks will be the same size.
% these two values do not need to be the same
blockSizeR = 128; % Rows in block.
blockSizeC = 128; % Columns in block.
% Figure out the size of each block.
wholeBlockRows = floor(rows / blockSizeR);
wholeBlockCols = floor(columns / blockSizeC);
trailing_rows = rows - wholeBlockRows * blockSizeR;
trailing_cols = cols - wholeBlockCols * blockSizeC;
image3d_cell = mat2cell( YourImage, [blockSizeR * ones(1, wholeblockRows), trailing_rows], [blockSizeC * ones(1, wholeBlockCols), trailing_cols], size(YourImage, 3) );
Now image3d_cell will be a cell array, wholeBlockRows or wholeBlockRows+1 (if there are trailing rows), by wholeBlockCols or wholeBlockCols+1 (if there are trailing columns).
if trailing_rows == 0 && trailing_cols == 0
image3d = cat( ndims(YourImage)+1, image3d_cell{:} );
else
image3d = [];
warning('There were trailing rows or columns, could not form 3D image automatically');
end

Plus de réponses (3)

Image Analyst
Image Analyst le 13 Fév 2017
You can try one of the two ways shown in the FAQ: http://matlab.wikia.com/wiki/Split_image_into_blocks

muhamed ibrahim
muhamed ibrahim le 29 Mar 2024 à 21:03
Déplacé(e) : DGM le 29 Mar 2024 à 22:11
%% dividing the image into 9 non-overlapping patches and store them in a cell array
im=imread('pic.jpg');
imshow(im)
s=size(im,1); % the pic is square and RGB
div=floor(s/3);
patches={}
n=0
k=0
z=0
pathes={}
for i=1:div:div*3
z=z+1;
for j=1:div:div*3
n=n+1;
k=k+1;
patches{n}=im(i:z*div,j:k*div,:);
if k==3
k=0
end
end
end
  2 commentaires
DGM
DGM le 29 Mar 2024 à 22:12
This code presumes that the image is square. If a nonsquare image is wide, it will be truncated. If a nonsquare image is tall, it will fail with an error.
muhamed ibrahim
muhamed ibrahim le 29 Mar 2024 à 22:50
Modifié(e) : muhamed ibrahim le 29 Mar 2024 à 22:52
Yes you are right. div in both main and nested loops can be changed to adapt to different image dimensions (tall or wide).

Connectez-vous pour commenter.


DGM
DGM le 29 Mar 2024 à 22:10
This has been asked and answered a bazillion times, so I'll just throw this out there again. If the goal is to subdivide an image, MIMT imdetile() and imtile() make it easy.
inpict = imread('peppers.png'); % any I/IA/RGB/RGBA/RGBAAA image
outstack = imdetile(inpict,[3 3]); % a 4D multiframe image
That's it. One line. Want to put it back together?
outpict = imtile(outstack,[3 3]); % a single-frame image
Bam. Done.
The tiling order and means of resolving divisibility are user-defined, but all tiles always have the same geometry. If the tile geometry is resolved by scaling or truncating, does that mean that the retiled image doesn't have the same geometry as the original? Maybe. See the synopses for MIMT imtile() and maketileable() for an example on how to conditionally correct for the changes made when detiling.
When is MIMT imdetile() not helpful? Imdetile() is meant for subdividing an arbitrary image into an integer 2D tiling. If you're trying to divide an image into blocks of a specific size, imdetile() is probably not the right tool.
Note that due to an unfortunate order of events, MIMT imtile() creates a name conflict with IPT imtile(). They are not the same or remotely interchangeable. I have yet to overturn MIMT in order to resolve it. As far as I'm concerned, IPT imtile() is an afterthought that should have been functionality already present in montage(), and MIMT tools are entirely capable of replacing the functionality anyway.
Man. I'm feelin sassy.

Community Treasure Hunt

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

Start Hunting!

Translated by