Converting a 3d array into a 4d array

8 visualizzazioni (ultimi 30 giorni)
Jaime Wu
Jaime Wu il 16 Set 2018
Risposto: DGM il 11 Lug 2022
counter = 0;
sizeImage = size(imageA);
aReshaped = zeros(100,100,3,sizeImage(1)/100);
for col = 1:sizeImage(1)/100
for row = 1:sizeImage(2)/100
counter = counter + 1;
aReshaped(:,:,:,counter) = imageA((1:100)+100*(row-1),(1:100)+100*(col-1),:);
end
end
Hello all, is there a more efficient way to convert a 3d array into 4d array like this? I have a 1000*1000*3 image and want to slice it into 100*100 chunks and put each chunk into a 4d array. I can do this with loops but it is very slow for larger images, and I have also messed around with reshape function but doesn't seem to work.

Risposte (2)

Walter Roberson
Walter Roberson il 16 Set 2018
sizeImage = size(imageA);
splits = {100*ones(1, sizeImage(1)/100)), 100*ones(1, sizeImage(2)/100)), sizeImage(3)};
split_cell = mat2cell(imageA, splits{:});
aReshaped = cat(4, split_cell{:});

DGM
DGM il 11 Lug 2022
For what it's worth, MIMT imdetile() makes this sort of thing extremely easy to write. It's just one line.
% image is 876x1314px
% divide into 73x73px blocks, i.e. a 12x18 tiling
inpict = imread('llama.jpg');
% detile the image columnwise as in the original code
%outstack = imdetile(inpict,[12 18],'direction','col');
% detile the image row-wise for sake of demo readability with montage()
outstack = imdetile(inpict,[12 18],'direction','row');
% what is the size of the 4D array?
outsize = imsize(outstack)
outsize =
73 73 3 216
% display the 4D stack with padding between the tiles
montage(outstack,'size',[12 18],'bordersize',[2 2])
As to what's fastest, imdetile() detiles using loops internally. In my testing, I have seen no significant speed disadvantage compared to when I had it using cell array methods internally, though tests on other hardware or versions may prove differently.
That said, there may be a speed disadvantage when comparing imdetile() against a very minimalist routine based on either method. Because imdetile() can also support detiling images which are not integer-divisible by a given tiling, there is a potentially significant amount of work that may go into preparing the image to be detiled. That's the price you pay for having a higher-level convenience tool.
One last thing...
Going back to OP's example, you might want to preallocate the output array such that it's the same class as the input. Before you think to do this for sake of universal compatibility:
outstack = zeros(tileheight,tilewidth,numchannels,numtiles,class(inpict));
Be aware that this will throw an error if inpict is a logical image and you're using anything older than R2016a. That might not be such a relevant point today, but I think it would have been in 2018.

Categorie

Scopri di più su Image Processing Toolbox in Help Center e File Exchange

Prodotti


Release

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by