【问题标题】:Convert 16-bit Tiff image to 8-bit RGB将 16 位 Tiff 图像转换为 8 位 RGB
【发布时间】:2019-06-25 18:34:23
【问题描述】:

我正在处理一些卫星图像,由 16 位 .tiff 图像组成。颜色编码为每通道 16 位。我想知道如何将这些图像转换为普通的 8 位 RGB 以进行进一步的 CNN 处理。

我尝试过 OpenCV (cv2.read('file',-1)) 和 PIL (read('file')),但这两个包无法识别和读取 16 位 tiff 图像。

【问题讨论】:

  • "16bit tiff 图像转 RGB"? tiff 是一种图像文件格式,而 RGB 是一种色彩空间/模式。目前还不清楚您要如何处理 .tiff 文件
  • @JohnHennig 是的,每通道 16 位

标签: python tiff


【解决方案1】:

通常,当您想在 Python 中读取或写入任何位深度和​​格式的图像时,最好使用ImageIO。顾名思义,它的单一目标是输入/输出图像。唯一警告:它可能会忽略图像的元数据。也就是说:它可能无法正确处理定义颜色空间而非标准 sRGB 的图像,或者它可能无法保持图像的预期方向。

你会读到图片,比如example.tif,就像这样:

import imageio
image = imageio.imread('example.tif')

至于转换,这只是基本的数学运算。您将在其中接收像素数据的数据结构是 NumPy 数组。内省image.shapeimage.dtype。您应该期望您的图像具有(y, x, 3) 中的shape,其中y 是垂直方向的像素数,x 是水平方向的像素数,3 代表三个颜色通道:红色、绿色, 蓝色的。它的dtype(数据类型)应该是uint16,意思是无符号的16位整数。

旁注:由于有三个颜色通道,每个通道都以 16 位分辨率进行采样,因此图像的颜色深度通常被描述为“48 位”(每像素)。

16 位整数的范围在 0 到 65535 (= 216−1) 之间。它们需要被强制为 8 位范围:0 到 255 (= 28-1)。所以除以 256(= 28):

image = image / 256

这将产生一个浮点像素值数组。它的数据类型必须显式转换为 8 位整数才能删除任何分数。

image = image.astype('uint8')

同样,更有效地,您还可以bit-shift 右侧 8 位的 16 位值:

image = (image >> 8).astype('uint8')

这使得转换速度更快(现代硬件的两倍左右),因为它跳过了浮点运算。

然后,要么使用最终的image 数组进行进一步处理,要么将其保存到新文件中:

imageio.imwrite('example.png', image)

【讨论】:

    【解决方案2】:

    如果您只想将.tiff 文件的色彩空间转换为RGB。然后尝试:-

    from PIL import Image
    
    img = Image.open(r"Path_to_tiff_image")
    img = img.convert("RGB")
    img.save(r"path_of_destination_image")
    

    上面的代码,首先打开一个.tiff的图片,然后把它的颜色模式改成RGB。然后将其保存到目标位置。

    【讨论】:

    • PIL 无法识别 16 位 tiff 图像...\n 它给出错误:无法识别图像文件 '/spacenet_sample/spacenet_sample/AOI_2_Vegas_Train/RGB-PanSharpen/RGB-PanSharpen_AOI_2_Vegas_img225.tif'
    • @Qianhui Liang:更好的是,上传图片并在您的问题中添加指向它的链接。
    • @QianhuiLiang PIL,原生支持 16 位 3 通道的 tiff 图像,如果它们未压缩,如果在尝试打开 tiff 文件时出现错误,则可能是压缩文件. Read More About this 在官方 PIL .tiff 文档中
    【解决方案3】:

    嘿,我使用tifffile 来处理文件和我在此处的不同线程中找到的计算,用于将 16 位图像重新缩放为 8 位。

    import numpy as np
    import tifffile as tif
    import cv2
    
    image = tif.imread('/home/trance/test.tiff')
    
    # Rescale 16-bit to 8-bit
    img_rescaled = 255 * (image - image.min()) / (image.max() - image.min())
    
    # Colourising image and saving it with opencv
    img_col = cv2.applyColorMap(img_rescaled.astype(np.uint8), cv2.COLORMAP_INFERNO)
    cv2.imwrite('/home/trance/test.png', img_col)
     
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 2012-07-17
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多