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

时间:2018-05-14 06:49:04

标签: python numpy data-conversion openexr

我正在使用OpenEXR来读取Python中的EXR文件。我有半数据的R,G和B通道(float16)。使用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的范围内。

有什么想法吗?谢谢。

添加此处提到的def的代码getChanEXR(只是基于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

1 个答案:

答案 0 :(得分:1)

我对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()

然后将其转换为8位

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