使用浮点值编写图像

时间:2012-12-22 13:53:07

标签: image matlab file-io floating-point floating-point-conversion

我的代码读取RGB图像,处理它以产生浮点结果。如何在Matlab 7.6.0(R2008a)中将这些值作为图像写入,保持这些浮点值?

6 个答案:

答案 0 :(得分:2)

实际上可以将64位像素数据(即表示double-precision floating-point value所需的位数)拟合成某些图像格式,特别是PNG。您甚至可以准确地恢复数据。关键是将所有内容编码为uint16值,并使用Truecolor RGB image(16位数据的3个颜色平面)以及Alpha透明度贴图(另外16位)。这是编码步骤:

data = rand(4);              % Just some sample data, a small 4-by-4 matrix
hexData = num2hex(data(:));  % Get the 16 digit hex codes for each pixel
C = mat2cell(hexData, numel(data), [4 4 4 4]);  % Split the hex codes into 4 groups of 4
C = cellfun(@(c) {uint16(hex2dec(c))}, C);  % Convert each hex value into a 16 bit integer
colorData = reshape([C{1:3}], [size(data) 3]);  % 4-by-4-by-3 uint16 color data
alphaData = reshape(C{4}, size(data));          % 4-by-4 uint16 alpha data
imwrite(colorData, 'double_data.png', 'Alpha', alphaData);  % Save image

您现在拥有一个有效的图像文件,但如果您查看它可能看起来像随机垃圾。现在,您可以像这样解码它:

[imColor, ~, imAlpha] = imread('double_data.png');  % Load image
imSize = size(imColor);  % Get image size
imHex = [dec2hex(imColor(:, :, 1)) ...  % Convert each uint16 to hex and concatenate
         dec2hex(imColor(:, :, 2)) ...
         dec2hex(imColor(:, :, 3)) ...
         dec2hex(imAlpha)];
imdata = reshape(hex2num(imHex), imSize(1:2));  % Reproduce data

和平等检查:

>> isequal(imdata, data)

ans =

  logical

   1           % it's the same!

答案 1 :(得分:1)

用于表示数字图像的每个元素的比特数称为图像的比特深度。位深度告诉我们图像元素可以采用的离散级别的数量。这些元素是存储为整数类型还是浮点类型是无关紧要的:位深度确切地确定了可能有多少个离散级别。

如何解释位深度取决于图像是灰度还是彩色。例如,8位灰度图像的强度为[0,255],而24位彩色图像的强度为[0,255]。使用这种命名法是因为存储具有8位红色,绿色和蓝色分量的彩色像素需要24位。为了避免混淆,彩色图像通常通过每个颜色通道的位数来调用。例如,PNG格式每个通道最多支持16位,或者对于带有alpha层的truecolor(RGB),总共支持48位。

imwrite的文档列出了MATLAB中可用的格式和位深度。

以最高精度从MATLAB保存彩色图像(MxNx3矩阵):

%// Assume an image called 'im' of type double.
%// First normalize to fall into [0,1].
im = im - min(im(:)); %// Save these numbers somewhere
im = im / max(im(:)); %// if you need to recover the original values later!
%// Best PNG quality.
imwrite(im,'image.png','bitdepth',16);

如果您需要更高的精度,则必须以一般数据格式而不是专门的图像格式保存图像。

答案 2 :(得分:1)

具有浮点值的图像可以用tiff图像格式写入。这是一个例子:

A=single(7.6*rand(10,10))

t = Tiff('test.tif', 'w'); 
tagstruct.ImageLength = size(A, 1); 
tagstruct.ImageWidth = size(A, 2); 
tagstruct.Compression = Tiff.Compression.None; 
tagstruct.SampleFormat = Tiff.SampleFormat.IEEEFP; 
tagstruct.Photometric = Tiff.Photometric.MinIsBlack; 
tagstruct.BitsPerSample = 32; 
tagstruct.SamplesPerPixel = 1; 
tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky; 
t.setTag(tagstruct); 
t.write(A); 
t.close();

B=imread('test.tif')

答案 3 :(得分:1)

以下函数将单精度灰度或RGB图像写入tif文件。你会发现,如果像素值在(0,1)的范围内,Windows资源管理器可以很好地处理单精度图像。当您阅读它时,您可以照常使用pm2 start app.js -x -- --prod

imread

答案 4 :(得分:0)

如果您的RGB值超出范围(0,1),只需将RGB值转换为0和1.如果要恢复原始浮点值,可以将转换值保存为图像文件名的一部分

答案 5 :(得分:0)

保存图像时,查看者需要知道值的完整可能范围。 常见的约定是值为float,范围为[0..1],当值为uint8时,范围为[0..255]等。

当您使用像2.34这样的浮点值保存图像时,您应该问问自己观众将如何解释它?

我的回答是:你做不到。您应该将值转换为有效范围,然后保存它。例如,如果浮点范围是[0..10],则可以将所有值乘以1000并保存为uint16。这样你就可以(几乎)保持浮动值的准确性。

相关问题