将3通道16位图像转换为8位,同时保留颜色

3

我有一张 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')

https://dev59.com/R2Yq5IYBdhLWcg3weAaj 这正是我想要的。 - arrhhh
2个回答

2
我猜您想要应用自适应范围调整。
在全局最小值和全局最大值之间进行线性“拉伸”是一种简单的解决方案。找到下限和上限百分位数比最小值和最大值更稳健。
以下是一个例子:
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:
输入图像描述

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

请让我知道我的猜测是否正确。


嘿,谢谢,这看起来很有趣。我已经发布了想要的回答,但这似乎是一个不错的小技巧,我一定会记在心里。 - arrhhh

1
我会提取这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])

让我知道这是否有帮助。


谢谢,这看起来非常不错。 - arrhhh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接