【问题标题】:Converting 3 channel16 bit image to 8 bit while preserving color [duplicate]在保留颜色的同时将 3 通道 16 位图像转换为 8 位 [重复]
【发布时间】:2020-02-04 14:34:02
【问题描述】:

我有一个 3 通道 16 位图像的 tiff 文件。我想将它们转换为 8 位 3 通道图像,但是当我进行简单的缩放时,我发现那些主要是红色的图像变成了全黑。有没有办法在保留原始 16 位图像的颜色的同时进行这种转换。现在我有这个代码。

for r in root_:
files = os.listdir(r)
for f in files:
    if "tif" in f[-3:]:
        filepath = r+"/"+f 
        tif = TIFFfile(filepath)
        samples, sample_names = tif.get_samples()
        test = np.moveaxis(samples[0], 0, 2)
        img8 = (test/256).astype('uint8')

【问题讨论】:

标签: python image image-processing tiff


【解决方案1】:

我猜你想应用自适应范围调整。

在某个全局最小值和全局最大值之间进行线性“拉伸”是一种简单的解决方案。
找到下百分位数和上百分位数是比最小值和最大值更稳健的解决方案。

这是一个例子:

import cv2
import numpy as np

# Build input image for testing
test = cv2.imread('chelsea.png').astype(np.uint16) * 100

# lo - low value as percentile 0.1 (1/1000 of test values are below lo)
# hi - high value as percentile 99.9 (1/1000 of test values are above hi)
lo, hi = np.percentile(test, (0.1, 99.9))

# Apply linear "stretech" - lo goes to 0, and hi goes to 255
img8 = (test.astype(float) - lo) * (255/(hi-lo))

#Clamp range to [0, 255] and convert to uint8
img8 = np.maximum(np.minimum(img8, 255), 0).astype(np.uint8)

#Display images before and after linear "stretech":
cv2.imshow('test', test)
cv2.imshow('img8', img8)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果:

测试:

img8:

尝试修改您的问题,以便减少猜测。

如果我的猜测是正确的,请告诉我。

【讨论】:

  • 嘿,谢谢,这看起来很有趣,我发布了我想要的答案,但这看起来像是一个巧妙的小技巧,请记住它
【解决方案2】:

我会提取 3 个频道:

c1 = test[:,:][0]
c2 = test[:,:][1]
c3 = test[:,:][2]

使用辅助函数将它们缩放到 8 位:

def bytescale(image, cmin=None, cmax=None, high=255, low=0):

    if image.dtype == np.uint8:
        return image

    if high > 255:
        high = 255
    if low < 0:
        low = 0
    if high < low:
        raise ValueError("`high` should be greater than or equal to `low`.")

    if cmin is None:
        cmin = image.min()
    if cmax is None:
        cmax = image.max()

    cscale = cmax - cmin
    if cscale == 0:
        cscale = 1

    scale = float(high - low) / cscale
    bytedata = (image - cmin) * scale + low
    return (bytedata.clip(low, high) + 0.5).astype(np.uint8)

对通道进行缩放:

c1new = bytescale(c1)
c2new = bytescale(c2)
c3new = bytescale(c3)

重新组合:

x = np.array([c1new, c2new, c3new])

如果这有帮助,请告诉我。

【讨论】:

  • 感谢这看起来真的很整洁
猜你喜欢
  • 2011-04-23
  • 2012-07-17
  • 2013-01-24
  • 2014-08-18
  • 1970-01-01
  • 2015-08-04
  • 1970-01-01
  • 2017-02-18
  • 2022-11-25
相关资源
最近更新 更多