Convert image into Patches of size 64*64 and get each patch

Hello, I have RGB image dataset.I want to convert an image into patches and save each patch.How to do this in matlab. The patch size should be 64*64

3 Comments

I = imread('000000_10.png');
imSz = size(I);
patchSz = [64 64];
xIdxs = [1:patchSz(2):imSz(2) imSz(2)+1];
yIdxs = [1:patchSz(1):imSz(1) imSz(1)+1];
patches = cell(length(yIdxs)-1,length(xIdxs)-1);
for i = 1:length(yIdxs)-1
Isub = I(yIdxs(i):yIdxs(i+1)-1,:);
for j = 1:length(xIdxs)-1
patches{i,j} = Isub(:,xIdxs(j):xIdxs(j+1)-1);
end
end
###try this###
@Rajesh Das, and should be down below in the official "Answer" section with all the other answers of this question.

Sign in to comment.

 Accepted Answer

Hi Tahir, try this:
I = imread('rice.png');
imSz = size(I);
patchSz = [64 64];
xIdxs = [1:patchSz(2):imSz(2) imSz(2)+1];
yIdxs = [1:patchSz(1):imSz(1) imSz(1)+1];
patches = cell(length(yIdxs)-1,length(xIdxs)-1);
for i = 1:length(yIdxs)-1
Isub = I(yIdxs(i):yIdxs(i+1)-1,:);
for j = 1:length(xIdxs)-1
patches{i,j} = Isub(:,xIdxs(j):xIdxs(j+1)-1);
end
end
This produces a cell of your 64x64 patches:
>> patches
patches =
[64x64 uint8] [64x64 uint8] [64x64 uint8] [64x64 uint8]
[64x64 uint8] [64x64 uint8] [64x64 uint8] [64x64 uint8]
[64x64 uint8] [64x64 uint8] [64x64 uint8] [64x64 uint8]
[64x64 uint8] [64x64 uint8] [64x64 uint8] [64x64 uint8]
And you can access each one:
figure, imagesc(patches{2,3})
Did that do what you wanted?
Thanks, Sven.

6 Comments

hello. its work well on 256 by 256 image but i have 512 by 512 image. it gives the following error. Index exceeds matrix dimensions.
What will be the code if instead of RGB image its a Grayscale image?
Hello Sven,
I've tried this code, I gave RGB image as an input but it is returning patches in a grayscale. How this code will work, if we need patches in RGB as well??
I = imread('flamingos.jpg');
imSz = size(I);
patchSz = [64 64];
xIdxs = [1:patchSz(2):imSz(2) imSz(2)+1];
yIdxs = [1:patchSz(1):imSz(1) imSz(1)+1];
patches = cell(length(yIdxs)-1,length(xIdxs)-1);
for i = 1:length(yIdxs)-1
Isub = I(yIdxs(i):yIdxs(i+1)-1,:,:);
for j = 1:length(xIdxs)-1
patches{i,j} = Isub(:,xIdxs(j):xIdxs(j+1)-1,:);
end
end
Hi! The code worked well. How can i recombine these patches to form an original image.

Sign in to comment.

More Answers (2)

This is answered by the FAQ in two different ways (mat2cell and indexing). Take your pick as to which is easier, more convenient, and intuitive for you.

11 Comments

hi, what if I wanted to get the glcm of each patches automatically ? im so sorry, this is the first time im work on matlab.
I have following this code as mentioned and adding code for extracting GLCM. it works to get the patches but I still make mistake when I ad glcm code. still get error in :
Error in GLCM1 (line 53)
baseFileName = ca(k).name;
here's the code that I've followed :
folder = fullfile('D:\ProgramFiles\MATLAB\R2017a\bin\DATABC\Train\G1');
fileNames = dir(fullfile(folder, '*.tif'));
baseFileName1 = '6a.tif';
fullFileName = fullfile(folder, baseFileName1);
if ~exist(fullFileName, 'file')
fullFileName = baseFileName1;
if ~exist(fullFileName, 'file')
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
h=zeros(28,4);%row->no. of image, column->no. of feature
% Create blocks
rgbImage = imread(fullFileName);
gr = rgb2gray(rgbImage);
imshow(gr);
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
drawnow;
[rows, columns, numberOfColorBands] = size(gr);
blockSizeR = 100; % Rows in block.
blockSizeC = 100; % Columns in block.
% The size of each block in rows.
wholeBlockRows = floor(rows / blockSizeR);
blockVectorR = [blockSizeR * ones(1, wholeBlockRows), rem (rows,blockSizeR)];
% The size of each block in columns.
wholeBlockCols = floor(columns / blockSizeC);
blockVectorC = [blockSizeC * ones(1, wholeBlockCols), rem(columns, blockSizeC)];
% Create the cell array
% Divided up into blocks.
if numberOfColorBands > 1
ca = mat2cell(gr, blockVectorR, blockVectorC, numberOfColorBands);
else
ca = mat2cell(gr, blockVectorR, blockVectorC);
end
% Display all the blocks.
plotIndex = 1;
numPlotsR = size(ca, 1);
numPlotsC = size(ca, 2);
for r = 1 : numPlotsR
for c = 1 : numPlotsC
for k = 1:length(ca)
baseFileName = ca(k).name;
I = imread(baseFileName);
fprintf('plotindex = %d, c=%d, r=%d\n', plotIndex, c, r, I);
subplot(numPlotsR, numPlotsC, plotIndex);
rgbBlock = ca{r,c,I};
imshow(rgbBlock);
GLCM = graycomatrix(rgbBlock,'Offset', [0 1;-1 1;-1 0;-1 -1],'NumLevel', 8,'Symmetric',true);
stats = GLCM_Features1(GLCM,'Contrast, Correlation, Energy, Homogeneity');
h(k,1)= stats.contr(1);%contrast
h(k,2)= stats.corrp(1);%Correlation
h(k,3)= stats.homom(1);%Homogeneity
h(k,4)= stats.energ(1);%Energy
[rowsB, columnsB, numberOfColorBandsB] = size(rgbBlock);
caption = sprintf('Block #%xzd of %d\n%d rows by %d columns', ...
plotIndex, numPlotsR*numPlotsC, rowsB, columnsB);
title(caption);
drawnow;
plotIndex = plotIndex + 1;
end
end
end
could you help me please for this ?
i realy need your help, please.
ca is a cell array, not the result of a call to dir(). So why do you try to get the baseFileName = ca(k).name in the loop? It makes no sense. Somehow you took the FAQ code http://matlab.wikia.com/wiki/Split_image_into_blocks and altered it in a nonsensical way such that it no longer works. You do not need the base file name in the loop. In fact you do not need the look over k at all. Just follow the original code in the FAQ and put your call to graycomatrix inside the inner loop.
Get rid of that line, and the imread() line below it.
thank you so much for your help, sir. i'm sorry for my mistake. I just know now.
it's already run. but the problem is, how can I extract the glcm value from every single tile of an image, sir ? because when I run that code. it only extract the glcm of an image. And I need the glcm value not from an image but from each tile of the image. those glcm from each tile i will use for cluster coocurence matrix (CCM feature).
could u help me please, sir ?
Why do you think it's doing the whole image? You're passing in rgbBlock, not the whole image so it's only doing that one block.
so, how can I read it to get glcm of each tiles from whole image, sir ?
You get the matrix with this line of code:
GLCM = graycomatrix(rgbBlock,'Offset', [0 1;-1 1;-1 0;-1 -1],'NumLevel', 8,'Symmetric',true);
It is the GLCM for just one tile.
yes sir. so if I want to get glcm for all tiles. what should I do, sir ? im sorry I still don't get the idea.
glcm_output = blockproc(YourRGBMatrix, [blockSizeR, blockSizeC], @(block_struct) graycomatrix(block_struct.data(:,:,1), 'Offset', [0 1;-1 1;-1 0;-1 -1], 'NumLevel', 8, 'Symmetric',true), 'TrimBorder', false);
glcm_output will be a 2D matrix that is all of the glcm results concatenated together. So if the output of glcm is 8 x 8, and there are (say) 39 groups of 100 pixels vertically, and 48 groups of 100 pixels horizontally (say the images was 384 x 480), the output would be (39*8) x (48*8) which would be 312 x 384.
Only the first color plane will be examined in this code, because glcm is only for grayscale not for color. Instead of block_struct.data(:,:,1) you could use rgb2gray(block_struct.data) to convert to grayscale... but it would be more efficient to instead
glcm_output = blockproc(rgb2gray(YourRGBMatrix), [blockSizeR, blockSizeC], @(block_struct) graycomatrix(block_struct.data, 'Offset', [0 1;-1 1;-1 0;-1 -1], 'NumLevel', 8, 'Symmetric',true), 'TrimBorder', false);
With a slight bit of extra work you could use a real function instead of an anonymous function, and have that real function call GLCM_Features1 on the output of the graycomatrix, and pick out the required stats and return them.
I do have a version of blockproc() that uses a separate function, where you can do more complicated operations than in an anonymous function. It is attached.
There is also a function called graycoprops() that you may want instead of graycomatrix(). It gives you key features from the GLCM matrix.

Sign in to comment.

hello. its work well on 256 by 256 image but i have 512 by 512 image. it gives the following error. Index exceeds matrix dimensions.

Tags

Asked:

on 14 May 2015

Edited:

on 28 Apr 2022

Community Treasure Hunt

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

Start Hunting!