【问题标题】:Writing an image with floating point values使用浮点值写入图像
【发布时间】:2012-12-09 19:35:58
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    实际上可以将 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!
    

    【讨论】:

    • 图片或者它没有发生。
    • @AndrasDeak:你的意思是在我的帖子中看不到 16 像素的图像?就在那个时期旁边……还是那个时期?
    【解决方案2】:

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

    如何解释位深度取决于图像是灰度还是彩色。例如,8 位灰度图像的强度为 [0,255],而 24 位彩色图像 的强度为 [0,255]。使用此命名法是因为存储具有 8 位红色、绿色和蓝色分量的彩色像素需要 24 位。为了避免混淆,彩色图像通常以每个颜色通道的位数来调用。例如,PNG 格式支持每个通道最多 16 位,或带有 Alpha 层的真彩色 (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);
    

    如果您需要更高的精度,则必须将图像保存为通用数据格式而不是专用图像格式。

    【讨论】:

      【解决方案3】:

      具有浮点值的图像可以写入 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')
      

      【讨论】:

      • Photoshop 将无法打开此文件。
      • 正常,需要软件支持这种图片
      【解决方案4】:

      以下函数将单精度灰度或 RGB 图像写入 tif 文件。而且你会发现,这些天,如果像素值在 (0,1) 范围内,Windows 资源管理器可以很好地处理单精度图像。当你读回来时,你可以像往常一样使用imread

      function writeftif(outim,outfilename)
      t = Tiff(outfilename,'w');
      if size(outim,3)==3
          t.setTag('Photometric',Tiff.Photometric.RGB);
      elseif size(outim,3)==1
          t.setTag('Photometric',Tiff.Photometric.MinIsBlack);
      end
      t.setTag('Compression',Tiff.Compression.None);
      t.setTag('BitsPerSample',32);
      t.setTag('SamplesPerPixel',size(outim,3));
      t.setTag('SampleFormat',Tiff.SampleFormat.IEEEFP);
      t.setTag('ImageLength',size(outim,1));
      t.setTag('ImageWidth',size(outim,2));
      t.setTag('PlanarConfiguration',Tiff.PlanarConfiguration.Chunky);
      % Write the data to the Tiff object.
      t.write(single(outim));
      t.close();
      

      【讨论】:

        【解决方案5】:

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

        【讨论】:

        • 问题是我想将这些值保存为图像并保留这些浮点值,因为当我使用 imwrite 函数时,这些值将转换为无符号整数。
        【解决方案6】:

        保存图像时,查看者需要知道值的全部可能范围。 通常的约定是值是浮点数,范围是 [0..1],当值是 uint8 时,范围是 [0..255] 等等。

        当您使用像 2.34 这样的浮点值保存图像时,您应该问自己查看者如何知道如何解释它?

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

        【讨论】:

        • TIFF 支持浮点图像就好了。我不在乎观众用它做了什么。它是数据,没有充分的理由我不应该拥有一个值为例如的像素。 2.34。如果像素类型为浮点型,则范围为 MIN_FLOAT 到 MAX_FLOAT。哦,是的,您可以使用 Tiff 类来做到这一点。
        猜你喜欢
        • 2012-11-26
        • 1970-01-01
        • 2015-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多