Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中为EXR文件将float16转换为uint8_Python_Numpy_Data Conversion_Openexr - Fatal编程技术网

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

如何在Python中为EXR文件将float16转换为uint8,python,numpy,data-conversion,openexr,Python,Numpy,Data Conversion,Openexr,我正在使用OpenEXR读取Python中的EXR文件。我有R、G和B通道,有一半的数据(浮点16)。使用Numpy,我尝试将数据从float16转换为uint8(0-255种颜色),但没有成功 所以,我把R通道像素值放到一个变量rCh中。然后我将array.array转换为np.array,以便使用astype方法将其转换为uint8。我不熟悉这一点,所以当所有值都变为0时,我显然不正确。最初,值如下:0.0、2.9567511226945634e-14、1.2295237050707897e

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

所以,我把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 -= rCh.min()
rCh /= rCh.max()
然后将其转换为8比特

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

谢谢你的回答Filippo。我认为你的答案是正确的,但有一步让我无法回答。数据是以array.array的形式存在的,因此当我使用min或max时,它告诉我它不能与array.array一起使用。如果我使用np.asarray来转换它,所有的值都将变为0。在将数据转换为<代码之前,你应该规范化数据>np.uint8,您可以使用标准的python
min()和
max()
使用
array.array
或者您可以将其转换为numpy float数组,对其进行规范化,然后将其转换为8bit什么是
getChanEXR
?它不会显示在或中。getChanEXR只是我根据文档中的openEXR python代码创建的def。这就是我获取通道数据的方式。
def getChanEXR(curEXRStr、curChannel、dataType):#导入OpenEXR、Imath、array pt='none'如果dataType='HALF':pt=Imath.PixelType(Imath.PixelType.HALF)如果dataType='FLOAT':pt=Imath.PixelType(Imath.PixelType.FLOAT)如果dataType='UINT':pt=Imath.PixelType(Imath.PixelType.UINT)chanstr=OpenEXR.InputFile(curEXRStr).channel(curChannel,pt)chan=array.array('f',chanstr)return chan
截断是正确的;舍入会引入错误,例如255.6舍入到256,然后由于8位溢出而变成0。此外,
数组
是一种完全不同的数组类型。显然,
数组。数组
的混乱来自疯狂大师。不过,我们不清楚使用的是哪种数组正在使用@user2357112 uh进行初始化?如果您的数据在
[0,1]中进行了规范化,则不能使用
255.6
bleh,哎哟。我还以为你是在乘256,而不是255。你应该乘256然后截断,而不是乘255然后取整。乘255然后取整并不能平均地存储结果。@user2357112有趣的是,你有什么参考来证明截断更好吗?这是图像数据的特定内容吗违反直觉
rCh -= rCh.min()
rCh /= rCh.max()
rCh = np.asarray(rCh * 255, dtype=np.uint8)