I have a multitiff image which I want to store as a 3D array.
Here is the function I am using. However, I wanted to know if there is a way to vectorize the for loop at the end of the code to reduce processing time.
function Images = readMultiTiff(TifImage)
%Get the information in the multitiff image
info = imfinfo(TifImage);
%Get the number of images in the multitiff image
num_images = numel(info);
%Determine height and width
width = info.Width;
height = info.Height;
%Create an empty array the size of each image in the multitiff
BlankImage =zeros(width,height);
%Use that to build a 3D array to store all the tiff images in the multitiff
Images = uint16(zeros(size(BlankImage,2),size(BlankImage,1),num_images));
%Read and assign each image to SEMImages.
mywaitbar_handle = waitbar(0, 'Saving images...');
for k = 1:num_images
A = imread(TifImage, k);
Images(:,:,k) = A;
waitbar(k/num_images);
end
close(mywaitbar_handle)

 채택된 답변

DGM
DGM 2022년 2월 18일
편집: DGM 2022년 2월 18일

0 개 추천

Depending on the image sizes, the waitbar itself is probably wasting the majority of the time. Consider the following test. Attached is an 11 frame TIFF (i added the padding .txt extension so that it could be uploaded. just omit it)
% original method
a = timeit(@() testA())
% using simplified mcode
b = timeit(@() testB())
% time ratio
a/b
function testA()
fname = 'multipage.tiff';
%Get the information in the multitiff image
info = imfinfo(fname);
%Get the number of images in the multitiff image
num_images = numel(info);
%Determine height and width
width = info.Width;
height = info.Height;
% guess output class
if all([info.BitDepth] == 8)
cl = 'uint8';
elseif all([info.BitDepth] == 8)
cl = 'uint16';
end
Af = zeros(height,width);
A = cast(zeros(size(Af,1),size(Af,2),num_images),cl); % right order
mywaitbar_handle = waitbar(0, 'Saving images...');
for k = 1:num_images
A(:,:,k) = imread(fname, k);
waitbar(k/num_images);
end
close(mywaitbar_handle)
end
function testB()
fname = 'multipage.tiff';
%Get the information in the multitiff image
info = imfinfo(fname);
%Get the number of images in the multitiff image
num_images = numel(info);
%Determine height and width
width = info.Width;
height = info.Height;
% guess output class
if all([info.BitDepth] == 8)
cl = 'uint8';
elseif all([info.BitDepth] == 8)
cl = 'uint16';
end
A = zeros(height,width,num_images,cl); % just create the output the right size
for k = 1:num_images
A(:,:,k) = imread(fname, k);
end
end
Of course, I still can't run it here, since the waitbar won't work.
The times I get for a 256x256x11 image are:
a =
0.2518
b =
0.0104
timeratio =
24.1287
So the waitbar (and the extraneous allocation) make the first method take roughly 24-25 times as long.
So if you want to use a waitbar, use it for things that will take a long time between updates. If you want to guess the input class for the array allocation, the above example is only suggestive. It obviously only accounts for two cases and makes no distinction between (e.g.) uint16 and int16.

댓글 수: 3

Pratik Chettry
Pratik Chettry 2022년 2월 23일
편집: Pratik Chettry 2022년 2월 23일
Thanks DGM for the answer. I really appreciate your help. But I was looking for a way to vectorize the for loop.
DGM
DGM 2022년 2월 23일
If the TIFF file is structured as the example file is, then I don't think there is a way to do that in a single call to imread(). Similarly, there are other file formats which cannot be read/written completely in a single pass with imread/imwrite. If there is a way to do it with TIFF objects, I'm not familiar enough to be certain.
Thanks for the reply. I just wanted to be sure that I can speed up the code. This helps.

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

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

릴리스

R2020a

질문:

2022년 2월 18일

댓글:

2022년 2월 24일

Community Treasure Hunt

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

Start Hunting!

Translated by