필터 지우기
필터 지우기

How to divide an image into non-overlapping blocks size 4x4?

조회 수: 11 (최근 30일)
Anisa
Anisa 2013년 1월 4일
답변: Matt J 2021년 6월 14일
I want to divide a color image into a series of non-overlapping blocks size 4x4. Then, i want to know the minimum pixel value each block and arrange it into matrix just like before.
Can anyone help, please.
  댓글 수: 5
Anisa
Anisa 2013년 1월 5일
I'd edited my question. I want to divide a grayscale image of size 512x512 named Lena.bmp into a series of non-overlapping blocks of size 16x16 blocks. Then, i want to know the minimum pixel value each block and save it into matrix 16x16. I have try but it didn't work. When i checked the result between command window and workspace, it has different number.
I=imread('Lena.bmp', 'bmp');
c=mat2cell(I, [32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32], ...
[32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32]);
minTemp=zeros(16,16);
for i=1:16;
for j=1:16;
a = c{i,j};
min=a(1,1);
for s=1:32;
for t=1:32;
if a(s,t)<min
min = a(s,t);
end
end
end
minTemp(i,j)=min
end
end
Help me, please.
Jan
Jan 2013년 1월 5일
Using the command "min" would be much more efficient than using this as name of a variable in a double FOR loop:
minTemp(i,j) = min(c{i,j}(:));
But see the [EDITED] section in my answer for a faster and nicer solution.

댓글을 달려면 로그인하십시오.

채택된 답변

Image Analyst
Image Analyst 2013년 1월 5일
Anisa: Regarding your latest edit. If you want to do it that way, then you don't need the innermost two loops. Simply do it like this:
I=imread('lena.bmp');
c = mat2cell(I, [32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32], ...
[32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32]);
minOfBlocks=zeros(16,16);
subplot(1,2,1);
imshow(I);
title('Original Image', 'FontSize', 30);
for i=1:16
for j=1:16
a = c{i,j};
minOfBlocks(i,j)=min(a(:));
end
end
subplot(1,2, 2);
imshow(minOfBlocks, []);
title('Min of 32x32 Blocks', 'FontSize', 30);
  댓글 수: 3
Image Analyst
Image Analyst 2013년 1월 5일
It should be the same. Please add appropriate fprintf()'s to prove otherwise. Also you can upload your image to tinypic.com (or wherever) if you want me to use your image, or suggest a standard MATLAB demo image, like cameraman or moon or something (may need a resize to get to 512x512 though).
RAKESH KUCHANA
RAKESH KUCHANA 2021년 6월 14일
Hello Image Analyst, I want to split an image of 178*665 pixel format into 3 parts. Can you provide a code for this?

댓글을 달려면 로그인하십시오.

추가 답변 (6개)

Jan
Jan 2013년 1월 4일
편집: Jan 2013년 1월 5일
No loops, no blockproc:
RGB = rand(200, 100, 3); % Example data
s = size(RGB);
Blocks = reshape(RGB, [4, s(1)/4, 4, s(2)/4, 3]);
Blocks = min(min(Blocks, 1), 3);
But what does "arrange it into a matrix just like before"? Perhaps:
Blocks = repmat(Blocks, [4, 1, 4, 1, 1]);
Result = reshape(Blocks, s);
Now the non-overlapping 4x4 blocks have the same color, which is the minimal R, G and B component of the corresponding pixels.
[EDITED after Anisa's comment]
Im = imread('Lena.bmp');
blockIm = reshape(Im, 16, 32, 16, 32);
blockMin = min(min(blockIm, [], 1), [], 3);
Result = reshape(blockMin, 32, 32);
  댓글 수: 3
sumit kumar
sumit kumar 2015년 7월 23일
i have a image and want to divide in 16*16 block and then want all the blocks separately.How will i proceed.??

댓글을 달려면 로그인하십시오.


David
David 2013년 1월 4일
How does this work for you?
I = imread('AnisasImage.jpg');
I = rgb2gray(I);
for col = 1:4:size(I,2)-4
for row = 1:4:size(I,1)-4
block_minimums((row+3)/4,(col+3)/4) = min(min((I(row:row+4,col:col+4))));
end
end
  댓글 수: 1
David
David 2013년 1월 4일
You wanted colour didn't you.
I = imread('AnisasImage.jpg');
for col = 1:4:size(I,2)-4
for row = 1:4:size(I,1)-4
block_minimums((row+3)/4,(col+3)/4) = min(min(min((I(row:row+4,col:col+4,:)))));
end
end

댓글을 달려면 로그인하십시오.


Image Analyst
Image Analyst 2013년 1월 4일
Anisa, try this demo (that I've posted many times before). Just copy, paste, and run. It is pretty general and flexible. It splits both color and grayscale standard MATLAB demo images up into blocks, using blockproc() and using regular indexing (both methods). It even allows you to have images that are not a integer multiple of the block size and that is illustrated. So it pretty much handles every 2D situation.
% Demo to divide a color image up into blocks.
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);
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.');
  댓글 수: 2
Im@
Im@ 2015년 4월 14일
hello I would like you please to provide where i can change in the code the number of blocks i want
Image Analyst
Image Analyst 2015년 4월 19일
Change these lines:
blockSizeR = 150; % Rows in block.
blockSizeC = 100; % Columns in block.

댓글을 달려면 로그인하십시오.


Matt J
Matt J 2013년 1월 5일
Here's a way using this FEX file,
though I don't know if you're permitted to use it for course-work
out=cellfun(@(c) min(c(:)), mat2tiles(yourImage,[16,16]));

Jos (10584)
Jos (10584) 2015년 7월 23일
What about using the dedicated tool BLOCKPROC (provided you have the Image Processing Toolbox) which gives the following one-liner:
OUT = blockproc(IN, [4 4], @(BS) repmat(min(BS.data(:)), size(BS.data)))

Matt J
Matt J 2021년 6월 14일

카테고리

Help CenterFile Exchange에서 Convert Image Type에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by