Writing multilevel tiff from PNGs using blockedImage and setBlock

5 views (last 30 days)
Hi all.
I am trying to create a multilevel blockedImage (pyramid tiff) from 1530 individual PNG images, but I am having trouble creating and writing multiple resolution levels. I am however able to create a single level image using the code below; where sorted is a cell array containing the paths of all the images to be included.
I1 = imread(sorted{1});
blockSize = size(I1); % Get block size from original image frame
Ncol = 34;
Nrow = 45;
Nframes = Ncol*Nrow; % Total number of frames
%Create blocked image
destination = "test.tif";
bimSize = blockSize.*[Nrow Ncol 1];
initval = uint8(0);
bim = blockedImage(destination,bimSize,blockSize,initval, "Mode", 'w');
% Loop through each block in the blocked image image and insert image data from the input files.
h = waitbar(0,'Processing'); % Create status bar
frameCnt = 1; % Frame Counter for indexing
for i=1:Ncol % Loop through columns
for k=1:Nrow % Loop through rows
blocksubs = [k i 1]; % Index blocked image
blockData = uint8(imread(sorted{frameCnt})); % Read input image
setBlock(bim, blocksubs, blockData); % Write Color tif
waitbar(frameCnt/Nframes, h);
frameCnt = frameCnt+1;
end
end
bim.Mode = 'r'; % Set to Blocked image to "Read mode"
close(h);
I naively tried to create a two-level image by initially defining a two level blockedImage, and then writing a scaled version of each image to the second layer within the for loop, please see the code below. Unfortunately, my program throws and error stating that: "This level is closed for writing additional data." when trying to write the second block to the highest resolution (level 1).
scale = 0.2;
I1 = imread(sorted{1});
I2 = imresize(I1,scale);
blockSizeL1 = size(I1); % Get block size from original image
BlockSizeL2 = size(I2); % Get scaled block size
Ncol = 34;
Nrow = 45;
Nframes = Ncol*Nrow; % Total number of frames
%Generate blocked image for color mosaic
destination = "test.tif";
bimSize = [blockSizeL1;BlockSizeL2].*[Nrow Ncol 1];
initval = uint8(0);
bim = blockedImage(destination,bimSize,blockSizeL1,initval, "Mode", 'w');
% Loop through each block in the blocked image image and insert image data from the input files.
frameCnt = 1; % Frame Counter for indexing
for i=1:Ncol % Loop through columns
for k=1:Nrow % Loop through rows
blocksubs = [k i 1]; % Index blocked image
blockDataL1 = uint8(imread(sorted{frameCnt})); % Read input image
blockDataL2 = imresize(blockDataL1,scale); % Scale
setBlock(bim, blocksubs, blockDataL1,'Level',1);
setBlock(bim, blocksubs, blockDataL1,'Level',2);
frameCnt = frameCnt+1;
end
end
bim.Mode = 'r'; % Set to Blocked image to "Read mode"
- Is it only possible to write alle the images to one level at a time before proceeding to write the scaled images to the next level? I'd be grateful if anyone could point me in the right direction, or provide a small snippet showing how to create multiple resolutions levels and setting the blocksize of the different layers.
Kind regards
Kasper

Answers (1)

Ashish Uthama
Ashish Uthama on 6 May 2022
Unfortunately, its not easy to write to two different sub-directories in a TIFF file at the same time - hence the error.
From your first code snippet, it looks like you already know the ordering of where each 'block' is w.r.t to the large virtual image. My suggestion would be to write a custom Adapter directly for the folder of PNG files. It will likey be more efficient if you are processing large amounts of data.
(We also have a in-built 'folder of PNG files' adapter. But the naming convention might not match what you have. If you can share how your PNG files are named, or better - share the data somewhere, I can help you write one).
Else, you could choose a different format (any of the ones ending with 'blocks' in this list) will allow you to write both levels at the same time.

Community Treasure Hunt

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

Start Hunting!

Translated by