开发者

Integer-valued images in the [0, 2^32] range or higher. Support in MATLAB or/and OpenCV?

开发者 https://www.devze.com 2023-03-13 00:05 出处:网络
I was wondering if anybody has a recommendation for an image format that supports integer-valued images in the range [0, 2^32] or higher, e.g. [0, 2^64]. I am interested in solutions that may already

I was wondering if anybody has a recommendation for an image format that supports integer-valued images in the range [0, 2^32] or higher, e.g. [0, 2^64]. I am interested in solutions that may already be supported by MATLAB (& OpenCV, if possible), that is, image formats with library support with read & write access in MATLAB and C/C++ (e.g. OpenCV) for such images.

I can write my own read/write library, but I would like to avoid reinventing the wheel. If no such library exists, I am interested in generic formats that would facilitate the implementation of read/write library for such images.

Note: I believe MATLAB's support for indexed images in .png files is limited to 开发者_如何转开发integers in the [0, 2^16] range

Thanks


You could try TIFF.

MATLAB has a powerful interface: http://www.mathworks.com/help/techdoc/ref/tiffclass.html

For an example, look here: http://www.mathworks.com/help/techdoc/import_export/f5-123068.html#br_c_iz-1

or:

t = Tiff('uint32.tif','w');

imgdata=uint32(magic(10));
tagstruct.ImageLength = size(imgdata,1)
tagstruct.ImageWidth = size(imgdata,2)
tagstruct.Photometric = Tiff.Photometric.MinIsBlack
tagstruct.BitsPerSample = 32;
tagstruct.SampleFormat = Tiff.SampleFormat.UInt;
tagstruct.SamplesPerPixel = 1
tagstruct.RowsPerStrip = 16
tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky
tagstruct.Software = 'MATLAB'
t.setTag(tagstruct)

t.write(imgdata);

t.close();

info = imfinfo('uint32.tif');

data = imread('uint32.tif');
class(data)


As you note, PNG images can have a bit depth of up to 16 for grayscale images. However, you could be sneaky and convert your 32-bit or 64-bit data into a set of red, green, blue, and alpha channels and save it as a truecolor RGB image with alpha transparency, which will give you 4 channels of 16 bits each for a total of 64 bits to work with.

Here are a couple of examples...


Storing a 64-bit value in a PNG file:

The 64-bit number can be broken into 4 16-bit numbers and saved as follows:

value = intmax('uint64')-1;  %# Sample 64-bit value

%# Writing the value to a file:

redChannel = uint16(bitshift(value,-48));                  %# 16 bits for red
greenChannel = uint16(bitand(bitshift(value,-32),65535));  %# 16 bits for green
blueChannel = uint16(bitand(bitshift(value,-16),65535));   %# 16 bits for blue
alphaChannel = uint16(bitand(value,65535));                %# 16 bits for alpha
imageData = cat(3,redChannel,greenChannel,blueChannel);    %# Concatenate color
                                                           %#   channels to 3-D
imwrite(imageData,'test.png','Alpha',alphaChannel);        %# Create the file

%# Reading the value from the file:

[imageData,~,alphaChannel] = imread('test.png');    %# Load the image data
result = bitshift(uint64(imageData(:,:,1)),48)+...  %# Recover the 64-bit value
         bitshift(uint64(imageData(:,:,2)),32)+...
         bitshift(uint64(imageData(:,:,3)),16)+...
         uint64(alphaChannel);

And you should see that the original 64-bit number value is equal to the recovered 64-bit number result.


Storing 32-bit data in a PNG file:

The 32-bit data can be broken into 4 sets of 8-bit data and saved as follows:

data = [0 100 1000 2^32-1];  %# Sample vector of double values
data = uint32(data);         %# Convert to unsigned 32-bit values

%# Writing the data to a file:

redChannel = uint8(bitshift(data,-24));                  %# 8 bits for red
greenChannel = uint8(bitand(bitshift(data,-16),255));    %# 8 bits for green
blueChannel = uint8(bitand(bitshift(data,-8),255));      %# 8 bits for blue
alphaChannel = uint8(bitand(data,255));                  %# 8 bits for alpha
imageData = cat(3,redChannel,greenChannel,blueChannel);  %# Concatenate color
                                                         %#   channels to 3-D
imwrite(imageData,'test.png','Alpha',alphaChannel);      %# Create the file

%# Reading the data from the file:

[imageData,~,alphaChannel] = imread('test.png');    %# Load the image data
result = bitshift(uint32(imageData(:,:,1)),24)+...  %# Recover the 32-bit values
         bitshift(uint32(imageData(:,:,2)),16)+...
         bitshift(uint32(imageData(:,:,3)),8)+...
         uint32(alphaChannel);

And all of the values in data and result should be equal.


Take a look at HDF5: https://hdfgroup.org/HDF5/

This is actually the format Matlab 7+ stores mat files in, although Matlab completely throws away the strict definition that HDF only stores things row-major for "performance reasons", that can be a tiny bit problematic deal with. Matlab also provides a low and high level apis to work with HDF5, although a little oddly as previously indicated.

You will be able to work with whatever bit depths and number formats (ieee 754 single and double too) and channels you want without any practical limitations (up to 32 dimensions by default). It also lets you choose some lossless compression details better suited to your individual problems if you are to look at them - files tend to be smaller as a result. Like tiff, you can also store multiple images (ie datasets) within a single file and HDFView allows viewing in a variety of ways, including images in all sorts of palettes.

Every language/platform worth its salt has a binding to HDF5 so portability is great too.

0

精彩评论

暂无评论...
验证码 换一张
取 消