Divide 256*256 image into 4*4 blocks
Show older comments
I am working on a project of image processing (watermarking) & needs to divide 256*256 image into 4*4 blocks (overlaping) to get 4096 matrices.If anyone knows about it plz help me.
5 Comments
Oleg Komarov
on 22 Mar 2012
Are you sure you can't use blockproc?
Image Analyst
on 15 Apr 2013
If they're 4 by 4, you will perfectly tile 64 by 64 subimages. There will be no overlap of any 4 by 4 block unless you're planning on having gaps that aren't being processed.
Priyanka
on 22 Aug 2014
let me know if i can divide 256*256 gray scale image into 5*5 block or not if yes how i can proceed?
5fingers
on 26 Oct 2016
You can use function :
im2col()
Walter Roberson
on 26 Oct 2016
Interesting, I had not encountered (or had forgotten) im2col(). I see it outputs a single numeric matrix, though, not a cell array.
Answers (5)
Image Analyst
on 15 Apr 2013
Here's my standard "split an image up into blocks" demo. It does this two ways (you can pick your favorite way), and for two types of images (gray scale and color). It's very general so it could be shortened some if you have certain conditions, like you know that there is an integer number of blocks in the image (i.e., no partial blocks at the edges).
% Demo to divide an image up into blocks (non-overlapping tiles).
% The first way to divide an image up into blocks is by using mat2cell().
% In this demo, I demonstrate that with a color image.
% Another way to split the image up into blocks is to use indexing.
% In this demo, I demonstrate that method with a grayscale image.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
workspace; % Make sure the workspace panel is showing.
fontSize = 20;
% Read in a standard MATLAB color demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'peppers.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
% Read the image from disk.
rgbImage = imread(fullFileName);
% Test code if you want to try it with a gray scale image.
% Uncomment line below if you want to see how it works with a gray scale image.
% rgbImage = rgb2gray(rgbImage);
% Display image full screen.
imshow(rgbImage);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
drawnow;
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage)
%==========================================================================
% The first way to divide an image up into blocks is by using mat2cell().
blockSizeR = 150; % Rows in block.
blockSizeC = 100; % Columns in block.
% Figure out the size of each block in rows.
% Most will be blockSizeR but there may be a remainder amount of less than that.
wholeBlockRows = floor(rows / blockSizeR);
blockVectorR = [blockSizeR * ones(1, wholeBlockRows), rem(rows, blockSizeR)];
% Figure out the size of each block in columns.
wholeBlockCols = floor(columns / blockSizeC);
blockVectorC = [blockSizeC * ones(1, wholeBlockCols), rem(columns, blockSizeC)];
% Create the cell array, ca.
% Each cell (except for the remainder cells at the end of the image)
% in the array contains a blockSizeR by blockSizeC by 3 color array.
% This line is where the image is actually divided up into blocks.
if numberOfColorBands > 1
% It's a color image.
ca = mat2cell(rgbImage, blockVectorR, blockVectorC, numberOfColorBands);
else
ca = mat2cell(rgbImage, blockVectorR, blockVectorC);
end
% Now display all the blocks.
plotIndex = 1;
numPlotsR = size(ca, 1);
numPlotsC = size(ca, 2);
for r = 1 : numPlotsR
for c = 1 : numPlotsC
fprintf('plotindex = %d, c=%d, r=%d\n', plotIndex, c, r);
% Specify the location for display of the image.
subplot(numPlotsR, numPlotsC, plotIndex);
% Extract the numerical array out of the cell
% just for tutorial purposes.
rgbBlock = ca{r,c};
imshow(rgbBlock); % Could call imshow(ca{r,c}) if you wanted to.
[rowsB columnsB numberOfColorBandsB] = size(rgbBlock);
% Make the caption the block number.
caption = sprintf('Block #%d of %d\n%d rows by %d columns', ...
plotIndex, numPlotsR*numPlotsC, rowsB, columnsB);
title(caption);
drawnow;
% Increment the subplot to the next location.
plotIndex = plotIndex + 1;
end
end
% Display the original image in the upper left.
subplot(4, 6, 1);
imshow(rgbImage);
title('Original Image');
%==============================================================================
% Another way to split the image up into blocks is to use indexing.
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'cameraman.tif';
fullFileName = fullfile(folder, baseFileName);
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 1.
[rows columns numberOfColorBands] = size(grayImage);
% Display the original gray scale image.
figure;
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% 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.
row1 = row;
row2 = row1 + blockSizeR - 1;
col1 = col;
col2 = col1 + blockSizeC - 1;
% 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.
image3D(:, :, sliceNumber) = oneBlock;
sliceNumber = sliceNumber + 1;
end
end
% Now image3D is a 3D image where each slice,
% or plane, is one quadrant of the original 2D image.
msgbox('Done with demo! Check out the two figures.');
14 Comments
myetceteramail myetceteramail
on 16 Jan 2017
Edited: myetceteramail myetceteramail
on 16 Jan 2017
i tried to implement the code but it shows dimension error. i have a 64*64 image. i need to to convert it in an 3D array of 16*16*16 the code i modified was this.but it doesn't give me results it shows an error.what is the mistake can you tell.also how do i see each slice from the image3d matrix
Mohammad Manzurul Islam
on 7 Feb 2018
Hi Image Analyst, Can you please have a look at my query? Thanks.
https://au.mathworks.com/matlabcentral/answers/380967-how-to-calculate-multi-block-dct-of-an-image-where-block-size-are-2x2-4x4-and-8x8-thanks
Alejandro Cruz Rubio
on 30 May 2019
Hi Image Analyst, how can I discard a piece of block? I want to discard a piece of image which I know its dimensions but I want to keep the rest of blocks.
How can I do that?
Thank you.
Regards
Image Analyst
on 30 May 2019
If you have blockproc() use a special function, then just have something in that function that recognizes when the block is the block you want to ignore, and just return immediately.
Walter Roberson
on 30 May 2019
I am not sure what it means to discard a block? You cannot leave a hole in an image. You can potentially return nan in that section though.
Md Farhad Mokter
on 13 Jun 2019
I am using the first method for creating 64*64 patches. How can I store those created patches in my folder?
safe binwax
on 4 Aug 2020
Dears,
i would like to segment characters froman image how can i save each segmented characters in a single folder automaticaly or at a time rather than saving them manually one by one. please send me the matlab code if you have it thank you in advance.
Image Analyst
on 4 Aug 2020
Did you try imcrop() and imwrite() on your segmented characters?
Samantha Villanueva
on 9 Sep 2020
Hello please help graduate and help me code - to be able to have an image block segmented into 10 x 10 blocks. These blocks will be used for feature extraction phase. Thank you so much!!
Walter Roberson
on 9 Sep 2020
Image Analyst
on 9 Sep 2020
Samantha, didn't you like either of the two well commented ways I showed in my Answer? If so, why not? You simply have to change the parameters to what works with your image sizes. Not difficult at all.
Anas Alkahlout
on 8 Sep 2021
How can I divide the picture into two instead of four I did not understand how I want to edit the code
Image Analyst
on 8 Sep 2021
@Anas Alkahlout, you can do this
[rows, columns, numColors] = size(yourImage);
midRow = round(rows/2);
midCol = round(columns/2);
leftHalf = yourImage(:, 1:midCol, :);
rightHalf = yourImage(:, midCol + 1 : end, :);
topHalf = yourImage(1:midRow, :, :);
bottomHalf = yourImage(midRow + 1 : end, :, :);
Walter Roberson
on 8 Sep 2021
horizontal_top = YourImage(1:floor(end/2), :);
horizontal_bottom = YourImage(floor(end/2)+1:end,:);
The code for splitting left and right is similar.
The code for splitting along diagonals or circles or n-gons is more difficult.
Ashwin
on 20 Sep 2016
Edited: Walter Roberson
on 20 Sep 2016
Simple, use this function
function dividedImage = divideIntoBlocks(InputImage,BlockSize)
img1 = InputImage;
TOTAL_BLOCKS = size(img1,1)*size(img1,2) / (BlockSize*BlockSize);
dividedImage = zeros([BlockSize BlockSize TOTAL_BLOCKS]);
row = 1;
col = 1;
try
for count=1:TOTAL_BLOCKS
dividedImage(:,:,count) = img1(row:row+BlockSize-1,col:col+BlockSize-1);
col = col + BlockSize;
if(col >= size(img1,2))
col = 1;
row = row + BlockSize;
if(row >= size(img1,1))
row = 1;
end
end
end
end
2 Comments
Subhajit Chatterjee
on 5 Feb 2017
How to overlay each divided image(tile) into the original image with its corresponding index text on each tile?
sujata sankhwar
on 23 Feb 2017
how to use this function for 50% overlapping blocks. plz ans
Thomas
on 22 Mar 2012
Try this example:
A=rand(16,16); %matrix of 16*16
[a b] = size(A); % get the size of A =16*16
c=4;d=4; % reshape it into 4*4 matrices
l=0;
for i=1:c:a-3
for j=1:d:b-3
C=A((i:i+3),(j:j+3));
eval(['out_' num2str(l) '=C'])
l=l+1;
end
end
You should get 16 4*4 matrices with names out_0 to out_15
11 Comments
Oleg Komarov
on 22 Mar 2012
@Thomas, I hope you're trolling the OP.
You're suggesting to create 4096 matrices.
This should be a clear answer on why not to use eval!
For image processing tasks, usually blockproc can be used.
Oleg Komarov
on 22 Mar 2012
Did I just delete another comment? (wasn't intentional)
Thomas
on 22 Mar 2012
@ Oleg: I do not understand what you are saying.. 'trolling' is not a got word on a scientific forum.. (unless it was in humor :))
My understanding of the question is that the OP has a 256*256 matrix that her needs to split into 4096 matrices of size 4*4..
I have shown an example of 16*16 matrix being split into 4*4 matrices.. the OP should be able to follow the same procedure for his requirement
Also if the user cannot use blockproc (as it is part of the image processing toolbox) this might be an easier way to go.. Though I would just go with accessing the values via indexing instead of actually creating 4096 matrices..
Oleg Komarov
on 22 Mar 2012
I really don't think eval is ever a good solution. (Sooner or later I write a post why eval is mistakenly used to scale projects...and why it shouldn't be done)
Assuming no IP toolbox and the necessity to morph the inital matrix (otherwise as you say just indexing), the best solution is to create a 3d array, where each slice is a 4x4 matrix.
Otherwise a cell array or a structure.
mohammed
on 15 Apr 2013
if i want to find the variance of each matix how i can do it? and if i want multiple each Out matrix in value
Walter Roberson
on 15 Apr 2013
How have you stored your matrices, Mohammed ?
Reshma Jose
on 28 Oct 2018
How can we recombine these blocks back to A
Walter Roberson
on 28 Oct 2018
How have you stored your matrices, Reshma Jose ?
gaetan gildas
on 3 Feb 2021
thanks Thomas.It runs well
gaetan gildas
on 3 Feb 2021
thanks you once more. Now i will like to obtain the image 256*256 after working with 16*16 blocks?
Image Analyst
on 3 Feb 2021
Not sure what that ("obtain") means, but are you aware of imresize()?
aya elfatyany
on 11 Feb 2015
0 votes
i am working on project on security its major is secret sharing and after i made a permutation sequence to permute the pixels of the secret image . i want to take pixels of permuted image to form a section so how can i form a section?
1 Comment
Image Analyst
on 11 Feb 2015
I have no idea what that means. What is a section? For what it's worth, I've attached a very simplistic image scrambling script.
W.Khan
on 14 Oct 2017
Edited: Image Analyst
on 14 Oct 2017
Hello, I divide my image into multiple blocks, but I want to save these new blocks to a folder. But I can't save it to another folder.
for i=1:10
a=rgbBlock;
imwrite (a,sprintf('%d.jpg',i));
end
All the new blocks are the same. I mean that the new blocks replace the old blocks of the image. Can you help how to do it? Also, how to do it for multiple images. Kindly comments
14 Comments
Image Analyst
on 14 Oct 2017
That's because you're not changing rgbBlock at all. It's the very same variable at every iteration!!!
Also, you need to put in the other folder name into fullfile():
for k = 1 : 10
oneBlock = rgbBlock; % Change this somehow!!!!!!!!!!!!!!
baseFileName = sprintf('Block #%d.png', k);
imwrite(oneBlock, fullfile(folder, baseFilename));
end
Saira Khalid
on 6 Jul 2018
Assalam o alaikum I divide my image into multiple blocks,64x64 blocksize but I want to save these new blocks in a new matrix of 256x256 But I can't save it to another matrix.help me please
Walter Roberson
on 6 Jul 2018
Saira Khalid: how are the blocks currently stored, and what order do you want to put them into the 256 x 256 matrix?
Saira Khalid
on 10 Jul 2018
Edited: Walter Roberson
on 10 Jul 2018
Here is my code, in which I have divided image in blocks. one block is 64x64. Then I have apply svd and inverse-svd by multiplying matrix. I don't know where is problem . This code is working fine but how to reconstruct these blocks/ save one by one in another matrix?
blockSizeR=64;
blockSizeC=64;
PlotNumber = 1;
for row = 1 : blockSizeR : 256
for col = 1 : blockSizeC : 256
% Let's be a little explicit here in our variables
% to make it easier to see what's going on.
row1 = row;
row2 = row1 + blockSizeR - 1;
col1 = col;
col2 = col1 + blockSizeC - 1;
% Extract out the block into a single subimage.
oneBlock = llband(row1:row2, col1:col2);
[u,s,v]=svd(oneBlock);%Applying svd
oneBlock=u*s*v';
% Specify the location for display of the image.
subplot(2, 2, PlotNumber);
imshow(oneBlock);
% Make the caption the block number.
caption = sprintf('Block #%d of 4', PlotNumber);
title(caption, 'FontSize', fontSize);
drawnow;
% Assign this slice to the image we just extracted.
image3D(:, :, PlotNumber) = oneBlock;
PlotNumber = PlotNumber + 1;
end
end
Walter Roberson
on 10 Jul 2018
Before the loop:
reconstructed = zeros(size(llband));
Inside the loop:
reconstructed(row1:row2, col1:col2) = oneBlock;
It is not obvious to me that you will have a use for your current assignment
image3D(:, :, PlotNumber) = oneBlock;
Possibly you will -- it depends upon what you want to do with what you calculated.
Ade Aulya
on 17 Sep 2018
i beg your pardon cause i'm still learning, and this is stupid question maybe, do you have any idea to what should we change this rgbBlock, sir ? I think this is the main problem. I've tried several times to change it, such as using 'blockSizeR and blockSizeC', or blockVector, but it didn't work. for this code :
for k = 1 : 10
oneBlock = rgbBlock; % Change this somehow!!!!!!!!!!!!!!
baseFileName = sprintf('Block #%d.png', k);
imwrite(oneBlock, fullfile(folder, baseFilename));
end
Walter Roberson
on 17 Sep 2018
Change it how ?
Ade Aulya
on 17 Sep 2018
like this sir :
rgbBlock = [blockVectorR,blockVectorC] ;
for k = 1 : 10
oneBlock = rgbBlock; % Change this somehow!!!!!!!!!!!!!!
baseFileName = sprintf('Block #%d.tif', x);
imwrite(oneBlock, fullfile('C:\Users\ASUS\Pictures\Data\G1\9a', baseFilename));
as I understand. maybe i'm wrong, sir ? please correct me. I really don't have any idea for that changing rgbBlock, sir.
Ade Aulya
on 17 Sep 2018
so sorry sir..i made blinder in baseFileName.
this is my code :
rgbBlock = [blockVectorR,blockVectorC] ;
for k = 1 : 10
oneBlock = rgbBlock; % Change this somehow!!!!!!!!!!!!!!
baseFileName = sprintf('Block #%d.tif', k);
imwrite(oneBlock, fullfile('C:\Users\ASUS\Pictures\Data\G1\9a', baseFilename));
but, still didn't work.
Walter Roberson
on 17 Sep 2018
oneBlock = rand();
??
If you want it changed, then change it.
Are you trying to ask how to change the block size? Those are controlled by
blockSizeR = 128; % Rows in block.
blockSizeC = 128; % Columns in block.
Note that in Image Analyst's code, blockVectorR and blockVectorC do not contain any content of the image: they deal with the size each block is to be broken into. All of the entries except possibly the last will be blockSizeR or blockSizeC respectively, with the last entry being such that the sum(blockSizeR) or sum(blockSizeC) adds up to the total number of rows or columns in the original image.
It really does not make sense to copy the block sizes into rgbBlock and then imwrite() that data.
Ade Aulya
on 17 Sep 2018
i see, sir. hank you for your information about that rgbBlock and imwrite.
no, sir. i'm trying to ask how to save all of those blocks of image to a folder after I divide it
i tried to use the code. it works but it just gave the same block. and Image Analyst said that we should change it somehow. but i don't have any ide to what should we change it or how should we, sir ?
Walter Roberson
on 19 Sep 2018
oneBlock = image3D(:,:,k);
Pandu Ananto
on 8 May 2019
i still dont understand how to change the total of the blocks...
if i want to get 4x4 blocks, i have to change
blockSizeR = 64;
blockSizeC = 64;
right? so that i get 4x4 each of them have 64 pixel row and col
i get this error
Subscripted assignment dimension
mismatch.
Error in coba_split (line 77)
image3D(:, :, sliceNumber)
= oneBlock;
why? pls help...
Image Analyst
on 9 May 2019
In blockproc() the parameters are the block sizes (horizontal and vertical). You can get the number of blocks by dividing the rows and columns by the block size. It's a simple relationship
rowsInImage = blockSizeR * numberOfBlocksVertically;
Do whatever math on that equation to get the parameter you need.
Categories
Find more on Image Arithmetic in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!