I'm working with stacks of microscopy images. By stack I mean a couple of images acquired one on top of the other, as illustrated in this very home-made diagram: (sorry for the quality) where:
H = Image height in pixels
W = Image Width in pixels
Z = number of slices in the stack (i.e. # of images).
What I want to do is measure, for every 'height' position in the stack, an orthogonal "WZ view", i.e. a cut off view along a rectangle such as the red one on the image. Right now I have the following code which works well:
DummyProjMatrixYZ = zeros(SliceNumber,ImageWidth,ImageHeight,3,'uint16');
for h = ImageHeight:-1:1
for z = 1:SliceNumber
DummyProjMatrixWZ(z,:,h,:) = MovieCell{z}(h,:,:); % MovieCell is a cell array containing the individual frames (i.e. slices in the stack) of dimensions (Height,Width,3).
end
end
The code works fine, but I have to loop through the whole slices for every "height unit", which is not optimal at all.
My question is: How could the previous code be vectorized in order to gain speed since I will eventually work with quite large datasets. I guess I have a brain freeze and do not know how to do it efficiently.
This basically looked like an indexing problem
to me. See if this works out for you -
%// Get all of the data into SliceNumber*ImageWidth x ImageWidth x 3 numeric
%// array. No more messing around with cell arrays is needed after this point.
A = vertcat(MovieCell{:});
%// Cocatenate data along dim3 to create a 2D array
A1 = reshape(permute(A,[1 3 2]),size(A,1)*size(A,3),[]);
%// Cut A1 after every ImageHeight rows to form a 3D array
A2 = permute(reshape(A1,ImageHeight,size(A1,1)/ImageHeight,[]),[1 3 2]);
%// Cut A2's dim3 into SliceNumber x 3 to create a 4D array
A3 = reshape(A2,ImageHeight,ImageWidth,SliceNumber,3);
%// Change the dimensions to match with original DummyProjMatrixWZ's
DummyProjMatrixWZ = permute(A3,[3 2 1 4]);
Shorter version -
%// Get all of the data into SliceNumber*ImageWidth x ImageWidth x Ch numeric
%// array. No more messing around with cell arrays is needed after this point.
A = vertcat(MovieCell{:});
%// Cut A at every H rows and resize to H x W x Slice*Ch to form a 3D array
A2 = permute(reshape(permute(A,[1 3 2]),ImageHeight,[],ImageWidth),[1 3 2]);
%// Cut A2's dim3 into Slice x Ch to create a 4D array and rearrange dims
DPrjMatWZ = permute(reshape(A2,ImageHeight,ImageWidth,SliceNumber,[]),[3 2 1 4]);
Here, Ch
denotes the number of channels used, which is 3
in the problem case and DPrjMatWZ
is the final output.