Vectorization to store images in a 3D array?

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.
Pratik Chettry
Pratik Chettry 2022 年 2 月 24 日
Thanks for the reply. I just wanted to be sure that I can speed up the code. This helps.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeLoops 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