How to divide 256X256 matrix into sixteen 16X16 blocks?

조회 수: 107 (최근 30일)
Malarvizhi
Malarvizhi 2013년 10월 10일
편집: Matt J 2023년 3월 29일
I am having pixel value of an image as 256X256 matrix. I want to divide it into sixteen 16X16 matrix (ie)an image into sub blocks. It is needed to compare each 16X16 with other. Can anyone help?
  댓글 수: 1
Roger Stafford
Roger Stafford 2013년 10월 10일
By my arithmetic, if you divide a 256x256 matrix into separate 16x16 blocks, there should be 256 of these blocks, not 16.

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

채택된 답변

David Sanchez
David Sanchez 2013년 10월 10일
You need to use mat2cell:
X = reshape(1:20,5,4)'
C = mat2cell(X, [2 2], [3 2])
celldisp(C)
This code returns
X =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
C =
[2x3 double] [2x2 double]
[2x3 double] [2x2 double]
C{1,1} =
1 2 3
6 7 8
C{2,1} =
11 12 13
16 17 18
C{1,2} =
4 5
9 10
C{2,2} =
14 15
19 2
In your case:
A = rand(256); % your matrix here
N = 16*ones(1,16);
B = mat2cell(A,N,N);

추가 답변 (5개)

Jacob
Jacob 2023년 3월 29일
편집: Jacob 2023년 3월 29일
In addition to @DGM's reshape method, here's another that passes through a 4D array instead of staying 3D. I've purposely picked numbers that aren't equal. I've found reshape methods tend to perform about 4–10× faster than mat2cell in my use cases but your results may vary. The ratio between the run times below is usually more similar for smaller values of nRep.
raw_img = imread('cameraman.tif'); % 256x256x1 uint8
raw_img = [raw_img; zeros(16, 256)]; % 272x256x1 (to make non-symmetric)
subX = 8; % number of pixels blocks have in the X/column direction
subY = 16; % number of pixels blocks have in the Y/row direction
nOutR = size(raw_img,1)/subY; % number of output block rows
nOutC = size(raw_img,2)/subX;
nRep = 100; %number of repetitions
tic
for iRep = 1:nRep
outstack_R2 = reshape(raw_img, subY, nOutR, subX, nOutC);
outstack_R2 = permute(outstack_R2, [1,3,4,2]);
outstack_R2 = reshape(outstack_R2, subY, subX, nOutR*nOutC);
end % end of loop over repetitions (for timing estimate)
toc
Elapsed time is 0.010731 seconds.
% Similar mat2cell option
tic
for iRep = 1:nRep
outstack_m2c = mat2cell(raw_img, subY*ones(nOutR,1), subX*ones(nOutC,1));
outstack_m2c = outstack_m2c';
outstack_m2c = outstack_m2c(:);
end % end of loop over repetitions (for timing estimate)
toc
Elapsed time is 0.110704 seconds.
% display the blocks
figure(1);
clf;
montage(outstack_R2,'Size',[nOutR nOutC],'bordersize',[5 5],'backgroundcolor',[1 1 1])
figure(2);
clf;
montage(outstack_m2c,'Size',[nOutR nOutC],'bordersize',[5 5],'backgroundcolor',[1 1 1])
  댓글 수: 1
DGM
DGM 2023년 3월 29일
편집: DGM 2023년 3월 29일
When I started being active on the forum a couple years ago, I was a bit confused that everyone was suggesting mat2cell() for this sort of thing. In writing MIMT tools, I had always found that rudimentary methods were faster, especially in older versions.
Still, I can see the merit of posting potentially sub-optimal solutions if they can be broadly useful while staying succinct enough to be learnable. That said, I'm still not going to write it that way in MIMT, especially if creating a cell array is not beneficial to the workflow.
P.S. I appreciate that your first answer is formatted, explained, documented, and demonstrated. That's how it's done!

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


DGM
DGM 2023년 3월 29일
편집: DGM 2023년 3월 29일
For what it's worth, this is how it'd be done in MIMT.
inpict = imread('cameraman.tif'); % 256x256
% detile the image into a 4D array
outstack = imdetile(inpict,[13 16]);
% display the blocks
montage(outstack,'bordersize',[5 5],'backgroundcolor',[1 1 1])
Note that the image geometry is not integer-divisible by the tiling.
If you had wanted the image to be detiled columnwise, you could to that too.
% detile the image into a 4D array
outstack = imdetile(inpict,[13 16],'direction','col');
% display the blocks
montage(outstack,'bordersize',[5 5],'backgroundcolor',[1 1 1])
... but don't expect montage() or MATLAB imtile() to be able to retile it.
On the other hand, MIMT imtile() is the counterpart to MIMT imdetile(), and they're made to work together.
% detile the image to a multiframe image
tiling = [13 16];
direction = 'row';
outstack = imdetile(inpict,tiling,'direction',direction);
% tile a multiframe image into a single image
outpict = addborder(outstack,1,1,'normalized'); % pad the stack for visualization
outpict = imtile(outpict,tiling,'direction',direction);
imshow(outpict)
For better or worse, imdetile() does the task using boring old loops and direct subscript addressing.
Are there disadvantages to using imdetile() and imtile()? Yes. Obviously, being part of a third-party toolbox and relying on a number of components of that toolbox is a burden to recommendation. The fact that TMW decided to create imtile() instead of adding export functionality to montage() results in a name conflict with MIMT imtile(), so that's an unfortunate inconvenience. In cases where it's desired to create fixed-geometry tiles, imdetile is more cumbersome than in the case where it's desired to subdivide the image into an integer tiling.
A lot of MIMT tools are designed around being convenient to use in an ad-hoc manner; to that end, there are often bits of elegance that get sacrificed.

Matt J
Matt J 2023년 3월 29일
편집: Matt J 2023년 3월 29일
You can download mat2tiles from,
C=mat2tiles(rand(256),[16,16])
C = 16×16 cell array
Columns 1 through 11 {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} Columns 12 through 16 {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double} {16×16 double}

Namwon Kim
Namwon Kim 2019년 8월 26일
x = zeros(256,256) % Input is (256,256).
a = size(x, 1);
b = size(x, 2);
numParts = 16
c = floor(a/numParts);
d = rem(a, numParts);
partition_a = ones(1, numParts)*c;
partition_a(1:d) = partition_a(1:d)+1;
e = floor(b/numParts);
f = rem(b, numParts);
partition_b = ones(1, numParts)*e;
partition_b(1:f) = partition_b(1:f)+1;
% Split matrix rows into partition, storing result in a cell array
% 256X256 matrix into sixteen 16X16 blocks
output = mat2cell(x, partition_a, partition_b);

AMEN BARGEES
AMEN BARGEES 2022년 7월 18일
x=your input marrix
ans= reshape(x,16,16,[]);
  댓글 수: 1
DGM
DGM 2023년 2월 22일
편집: DGM 2023년 2월 22일
That doesn't actually do what's required.
x = imread('cameraman.tif'); % 256x256x1 uint8
outstack = reshape(x,16,16,[]); % don't use 'ans' as a variable name!
% display the blocks
% i'm going to add some padding so that the block boundaries are clear
montage(outstack,'bordersize',[5 5],'backgroundcolor',[1 1 1])
FWIW, this is one way to do it with reshape():
x = imread('cameraman.tif'); % 256x256x1 uint8
outstack = reshape(x.',[],16,16);
outstack = permute(outstack,[2 1 3]);
outstack = reshape(outstack,16,16,[]);
% display the blocks
montage(outstack,'bordersize',[5 5],'backgroundcolor',[1 1 1])

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

카테고리

Help CenterFile Exchange에서 Image Data Workflows에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by