如何在 Python 中将 EXR 文件的 float16 转换为 uint8

2024-05-24

我正在使用 OpenEXR 读取 Python 中的 EXR 文件。我有带有半数据(float16)的 R、G 和 B 通道。我尝试使用 Numpy 将数据从 float16 转换为 uint8 (0-255 颜色),但没有成功。

        rCh = getChanEXR(imageFile, 'R','HALF')
        rCh = np.array(rCh).astype('uint8')

因此,我将 R 通道像素值放入变量 rCh 中。然后我将 array.array 转换为 np.array,以便我可以使用 astype 方法将其转换为 uint8。我对此很陌生,所以我显然不正确,因为所有值都变成0。最初,这些值是这样的:0.0、2.9567511226945634e-14、1.2295237050707897e-10等。

除了 float16 值之外,我还有一些需要标准化的常规浮点值。我认为我需要先对 float16 值进行标准化,然后才能将它们设置在 0-255 的范围内。

有任何想法吗?谢谢。

添加这里 getChanEXR 中提到的 def 的代码(只是一个基于 python OpenEXR 文档中用于获取通道数据的代码的自定义 def。

def getChanEXR(curEXRStr, curChannel, dataType):
    #import OpenEXR, Imath, array
    pt = 'none'
    if dataType == 'HALF':
        pt = Imath.PixelType(Imath.PixelType.HALF)
    if dataType == 'FLOAT':
        pt = Imath.PixelType(Imath.PixelType.FLOAT)
    if dataType == 'UINT':
        pt = Imath.PixelType(Imath.PixelType.UINT)
    chanstr = OpenEXR.InputFile(curEXRStr).channel(curChannel, pt)
    chan = array.array('f', chanstr)
    return chan

我没有太多经验array.array但我相信你可以将它转换为 numpy float 数组,这样使用起来更容易一些:

rCh = np.asarray(rCh, dtype=np.float)

如果您的数据标准化为[0,1]转换前将其乘以 255:

rCh = np.asarray(rCh * 255, dtype=np.uint8)

我相信它会截断小数部分。手动舍入应该更安全吧?(不太确定,请参阅评论中的讨论,我相信正确的方法会在这里犹豫不决,但我想这个问题值得针对您的具体用例进行更好的研究)

rCh = np.asarray(np.around(rCh * 255), dtype=np.uint8)

如果它没有标准化你可以这样做

rCh -= rCh.min()
rCh /= rCh.max()

然后将其转换为8bits

rCh = np.asarray(rCh * 255, dtype=np.uint8)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Python 中将 EXR 文件的 float16 转换为 uint8 的相关文章

随机推荐