Available that TIFF image of 16 bit unsigned integer has SMaxSampleValue of IEEE floating point number?

6 views (last 30 days)
I would like to store the image in TIFF with tags.
The origianl image is single/double type of floating point number (float), but I want to convert it to the 16 bit type of unsigned integer (uint) and save. Just in case, in order to restore the data from uint to float, I want to keep the maximum and minimum floating point number in TIFF tags (for example, SMaxSampleValue and SMinSampleValue). The conversion of single/double to 16 bit is conducted manually, so I need a max/min floating point number istead of using im2uint16, im2double, etc.
In my trials, however, it seems impossible. When we do store the data in uint type, we set the tag structures as a uint type (SampleFormat = 1) and it seems that SMax- and SMinSampleValues automatically set to uint type.
Is this really impossible? Or do you know how to solve it? Instead of using an additional file (Excel, etc.)...
clc; clear all; close all;
Img = double(imread('cameraman.tif'));
ImgFloat = Img/(max(Img,[],"all")+1);
figure; imagesc(ImgFloat); axis image; colormap('gray'); colorbar;
minImg = min(ImgFloat,[],"all");
maxImg = max(ImgFloat,[],"all");
Img16 = uint16(round((ImgFloat-minImg)/(maxImg-minImg)*(2^16-1)));
figure; imagesc(Img16); axis image; colormap('gray'); colorbar;
t = Tiff('myimage16.tif','w');
tagstruct.ImageLength = size(Img16,1);
tagstruct.ImageWidth = size(Img16,2);
tagstruct.Photometric = Tiff.Photometric.MinIsBlack;
tagstruct.BitsPerSample = 16;
tagstruct.SamplesPerPixel = 1;
tagstruct.SampleFormat = 1;
tagstruct.SMaxSampleValue = double(max(ImgN,[],"all")); %% It will be saved as uint type.
tagstruct.SMinSampleValue = double(min(ImgN,[],"all")); %% It will be saved as uint type.
tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
tagstruct.Software = 'MATLAB';
setTag(t,tagstruct)
write(t,Img16);
close(t);
  2 Comments
DGM
DGM on 21 Jan 2022
Afaik, those tags are stored in integers.
There are these, but I don't know what exactly might try to utilize them:
I don't know enough about libtiff to recommend anything.
I suppose you could always just store a string representation of those numbers in a tag like ImageDescription or something.
Youngju Kim
Youngju Kim on 22 Jan 2022
Edited: Youngju Kim on 23 Jan 2022
I found the page explaining how exproting to images in TIFF.
Here, about SMin- and SMaxSampleValue, their note is "Range of MATLAB data type specified for Image data".
I guess that it means the value follows image data type, and the tag information under the image follow the data type.
So, even if I put floating point number into SMin- and SMaxSampleValue of TIFF image in 16 bit uint type, the Value become uint type. I will lose numbers under decimal point.
It is my current conclusion...

Sign in to comment.

Accepted Answer

Karan Singh
Karan Singh on 30 Jan 2024
Edited: Karan Singh on 30 Jan 2024
Hi Youngju,
In TIFF files, the "SMinSampleValue" and "SMaxSampleValue" tags are indeed intended to represent the minimum and maximum sample values for the image data. However, these tags must match the data type of the image itself. If the image is stored as 16-bit unsigned integers, the "SMinSampleValue" and "SMaxSampleValue" tags will also be stored as 16-bit unsigned integers. Therefore, you cannot directly store the original floating-point range in these tags if the image is saved as a 16-bit integer.
One approach to circumvent this limitation is to use custom tags to store the original floating-point minimum and maximum values. The TIFF format allows for custom tags, but not all TIFF readers may recognize them. MATLAB's Tiff class can be used to create custom tags.
clc; clear all; close all;
Img = double(imread('cameraman.tif'));
ImgFloat = Img/(max(Img,[],"all")+1);
figure; imagesc(ImgFloat); axis image; colormap('gray'); colorbar;
minImg = min(ImgFloat,[],"all");
maxImg = max(ImgFloat,[],"all");
Img16 = uint16(round((ImgFloat-minImg)/(maxImg-minImg)*(2^16-1)));
figure; imagesc(Img16); axis image; colormap('gray'); colorbar;
% Create a TIFF file with custom tags for the floating-point range
t = Tiff('myimage16.tif','w');
tagstruct.ImageLength = size(Img16,1);
tagstruct.ImageWidth = size(Img16,2);
tagstruct.Photometric = Tiff.Photometric.MinIsBlack;
tagstruct.BitsPerSample = 16;
tagstruct.SamplesPerPixel = 1;
tagstruct.SampleFormat = Tiff.SampleFormat.UInt; % Unsigned integer format
tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
tagstruct.Software = 'MATLAB';
% Define custom tags
tagstruct.MinFloatingPointValue = minImg;
tagstruct.MaxFloatingPointValue = maxImg;
% Register custom tags with the TIFF library (using hypothetical tag IDs)
t.setTag('MinFloatingPointValue', 65000, 1, Tiff.TagType.Double, -1, false);
t.setTag('MaxFloatingPointValue', 65001, 1, Tiff.TagType.Double, -1, false);
% Set standard tags and write the image data
setTag(t, tagstruct);
write(t, Img16);
close(t);
Attached below is the documentation link that you may find helpful:
Hope this helps!

More Answers (0)

Categories

Find more on Convert Image Type in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!