Divide 256*256 image into 4*4 blocks

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

Are you sure you can't use blockproc?
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.
let me know if i can divide 256*256 gray scale image into 5*5 block or not if yes how i can proceed?
You can use function :
im2col()
Interesting, I had not encountered (or had forgotten) im2col(). I see it outputs a single numeric matrix, though, not a cell array.

Sign in to comment.

Answers (5)

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

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
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
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
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.
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.
I am using the first method for creating 64*64 patches. How can I store those created patches in my folder?
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.
Did you try imcrop() and imwrite() on your segmented characters?
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!!
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.
How can I divide the picture into two instead of four I did not understand how I want to edit the code
@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, :, :);
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.

Sign in to comment.

Ashwin
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

How to overlay each divided image(tile) into the original image with its corresponding index text on each tile?
how to use this function for 50% overlapping blocks. plz ans

Sign in to comment.

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

@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.
Did I just delete another comment? (wasn't intentional)
@ 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..
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.
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
How have you stored your matrices, Mohammed ?
How can we recombine these blocks back to A
How have you stored your matrices, Reshma Jose ?
thanks Thomas.It runs well
thanks you once more. Now i will like to obtain the image 256*256 after working with 16*16 blocks?
Not sure what that ("obtain") means, but are you aware of imresize()?

Sign in to comment.

aya elfatyany
aya elfatyany on 11 Feb 2015
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

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.

Sign in to comment.

W.Khan
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

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
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
Saira Khalid: how are the blocks currently stored, and what order do you want to put them into the 256 x 256 matrix?
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
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.
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
Change it how ?
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.
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.
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.
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 ?
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...
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.

Sign in to comment.

Asked:

on 22 Mar 2012

Commented:

on 8 Sep 2021

Community Treasure Hunt

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

Start Hunting!