i need to combined several blocks to one image

5 visualizzazioni (ultimi 30 giorni)
youbaa maa
youbaa maa il 29 Apr 2019
Modificato: DGM il 3 Giu 2022
hi everyone , i have divided a original imageof size 512x512 to blocks of 32x32 and now i need to combined this blocks , how will I do it
this is my code : i have this error message
part one : divided image in to 32*32
C=imread('lena.jpg');
C = rgb2gray(C);
% C=imread('D1.gif')
% x1=imresize(C,0.4);
x2=im2double(C);
[m,n,k]=size(x2) % and m=n with 1 channel k=1
ImageSize=m*n;
BlockD=32;
BlockSize=BlockD*BlockD;
NoOfBlock=ImageSize/BlockSize;
SubB=zeros(BlockD,BlockD,NoOfBlock); %arrays of blocks.
% X=zeros(BlockD,BlockD,NoOfBlock);
% important to convert uint8 to double when dialing with image.
% thats what ru asking for.
k=1;
for i=1:BlockD:m
for j=1:BlockD:n
x(:,:,k)=x2(i:i+BlockD-1,j:j+BlockD-1);
k=k+1;
end
end
part two: trying to combined image
img = ones(512,512);
countk =1;
for i=2:m
for j=2:n
ik=(mod(i,16))+1;
jk=(mod(j,16))+1;
img(i,j)=x(ik,jk,countk);
if (mod(i,16)==0) && (mod(j,16)==0);
countk = countk + 1;
end
end
end
i have this message error:
Index exceeds matrix dimensions.
Error in r (line 53)
img(i,j)=x(ik,jk,countk);

Risposte (2)

Image Analyst
Image Analyst il 25 Mag 2019
Here's a start
wideMatrix = [m1, m2]; % Stitch together horizontally.
tallMatrix = [m1;m2]; % Stitch together vertically.
You could also use horzcat() and vertcat() to stitch together more than 1 matrix I believe.

DGM
DGM il 3 Giu 2022
I suppose if I'm going to clean up the duplicate of this question, I should be willing to answer it to some degree.
While there are a lot of misused/unused variables, the real problems were at a higher level. It would make much more sense to do this any number of other ways.
C = imread('cameraman.tif');
BlockD = 128;
% this whole approach will break if image isn't square
x2 = im2double(C); % casting is not needed; duplicate variable
[m,n,~] = size(x2);
pagesize = m*n;
BlockSize = BlockD*BlockD;
NoOfBlock = pagesize/BlockSize; % not used for anything
SubB = zeros(BlockD,BlockD,NoOfBlock); % because this is not used for anything
% is SubB supposed to be x?
% why does reshaping an array require a change of class?
% X=zeros(BlockD,BlockD,NoOfBlock);
% important to convert uint8 to double when dialing with image.
% thats what ru asking for.
k = 1;
for i = 1:BlockD:m
for j = 1:BlockD:n
x(:,:,k) = x2(i:i+BlockD-1,j:j+BlockD-1); % not preallocated
k = k+1;
end
end
% this is just a mess. it'd be better to rethink this part
img = ones(m,n);
countk = 1;
for i = 2:m % why assign pixelwise instead of blockwise?
for j = 2:n % why are you offset by 1?
ik = (mod(i,16))+1; % use correct blocksize (32 instead of 16)
jk = (mod(j,16))+1;
img(i,j) = x(ik,jk,countk);
% this isn't going to cycle between blocks correctly either
if (mod(i,16)==0) && (mod(j,16)==0)
countk = countk + 1;
end
end
end
If the detiling routine were cleaned up, the retiling routine might be rewritten something like this:
% assumes that image geometry is compatible with block size
% assumes blocks and image are both perfect squares
% assumes image is detiled row-wise
% these are ridiculous assumptions
img = ones(m,n);
f = 1;
for bm = 1:sqrt(NoOfBlock) % loop through tile positions on output
for bn = 1:sqrt(NoOfBlock)
xidx = (bn-1)*BlockD + 1 : bn*BlockD;
yidx = (bm-1)*BlockD + 1 : bm*BlockD;
img(yidx,xidx) = x(:,:,f);
f = f+1;
end
end
Or maybe it could be written something like this instead:
% assumes that image geometry is compatible with block size
% assumes blocks and image are both perfect squares
% assumes image is detiled row-wise
% these are ridiculous assumptions
img = ones(m,n);
blocksperrow = sqrt(NoOfBlock);
for f = 1:NoOfBlock % loop through tile positions on input
bn = mod(f-1,blocksperrow)+1;
bm = ceil(f/blocksperrow);
xidx = (bn-1)*BlockD + 1 : bn*BlockD;
yidx = (bm-1)*BlockD + 1 : bm*BlockD;
img(yidx,xidx) = x(:,:,f);
end
If it's suitable for the detiled image to be handled as a cell array, both detiling and retiling can be made simpler (though not necessarily faster):
% if it's already assumed that images are integer-divisible by the blocksize
% then doing integer-subdivision of the image geometry should be equivalent
inpict = imread('cameraman.tif');
blocksize = 128;
% detile the image into a cell array
tiling = round(imsize(inpict,2)/blocksize);
bb = blocksize*ones(1,tiling(1));
imstack = mat2cell(inpict,bb,bb);
% retile from a cell array
outpict = cell2mat(imstack);
MIMT imdetile() and imtile() can also work, and they can also work on color images and image geometries which aren't integer-divisible by the tiling arrangement.
% if it's already assumed that images are integer-divisible by the blocksize
% then doing integer-subdivision of the image geometry should be equivalent
inpict = imread('cman_01.png'); % 256x256x3
blocksize = 128;
% detile the image
tiling = round(imsize(inpict,2)/blocksize);
imstack = imdetile(inpict,tiling); % 128x128x3x4
% retile the image
outpict = imtile(imstack,tiling); % 256x256x3
  2 Commenti
Image Analyst
Image Analyst il 3 Giu 2022
I think "cleaning up" could also include renaming variables. I hate it when people use things like m and n for the array size. It's so non-descriptive and I've seen many errors where people swap them in loops. It's actually very common that people swap rows and columns. Usually though it's because they think arrays are references by (x,y), but not noticing what variable is the row and column because of imprecise names is another cause. So I prefer
[rows, columns, slices] = size(x2)
rather than
[m,n,~] = size(x2);
DGM
DGM il 3 Giu 2022
Modificato: DGM il 3 Giu 2022
For general use, I try to avoid using size() like that anyway. The multiple-output syntax promotes the proliferation of groups of named scalar variables, and it will give the wrong size unless you request at least as many outputs as the array dimensionality. On the other hand, the vector-output syntax won't return a consistent vector length. Either way you use it, you have to babysit it with a bunch of safeguarding if there's any chance the array dimensionality might change.
MIMT imsize() returns the array size as a fixed-length vector. If you ask for the size of the first two dimensions of a 3-dimensional array (i.e. the page size of a potentially multichannel and/or multiframe image), it actually gives you the correct size.
You can have long variable names if you want. I find it incredibly cumbersome visually to use long names for variables which end up being used in indexing expressions.
... but using backwards x and y indices is right up there with
[row col] = size(myarray);
for Rows = 1:row
for Columns = 1:col
myarray(row,col) = somefunction(ofsomething);
end
end

Accedi per commentare.

Community Treasure Hunt

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

Start Hunting!

Translated by