我对 12 位相机的多帧 TIFF 图像进行了一些图像处理,并希望保存输出。但是,那PIL 文档 https://pillow.readthedocs.io/en/stable/handbook/concepts.html#concept-modes没有列出 12 位模式fromarray()
。 PIL 如何处理位深度以及如何确保保存的 TIFF 图像具有与原始图像相同的动态范围?
示例代码:
import os
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
# Read image file names
pathname = '/home/user/images/'
filenameList = [filename for filename in os.listdir(pathname)
if filename.endswith(('.tif', '.TIF', '.tiff', '.TIFF'))]
# Open image files, average over all frames, save averaged image files
for filename in filenameList:
img = Image.open(pathname + filename)
X, Y = img.size
NFrames = img.n_frames
imgArray = np.zeros((Y, X))
for i in range(NFrames):
img.seek(i)
imgArray += np.array(img)
i += 1
imgArrayAverage = imgArray/NFrames
imgAverage = Image.fromarray(imgArrayAverage) # <=== THIS!!!
imgAverage.save(pathname + filename.rsplit('.')[0] + '.tif')
img.close()
根据我的经验,12 位图像作为 16 位图像打开,前四个 MSB 全部为零。我的解决方案是将图像转换为 numpy 数组
arr = np.array(img).astype(np.uint16)
astype() 指令可能不是严格必要的,但看起来这是一个好主意。然后要转换为 16 位,请将二进制数字向左移动四位:
arr = np.multiply(arr,2**4)
如果您想使用 8 位,
arr = np.floor(np.divide(arr,2**4)).astype(np.uint8)
这里需要使用 astype() 来强制转换为 8 位整数。我认为 8 位截断隐式执行了 Floor() 函数,但为了以防万一,我将其保留了下来。
最后,转换回 PIL Image 对象就可以了:
img = Image.fromarray(arr)
对于您的特定用例,这将具有相同的效果:
imgAverage = Image.fromarray(imgarrayAverage.astype(np.uint16) * 2**4)
再次进行类型转换可能不是必需的,但它可能会节省您的时间,因为将 imgArray 除以 NFrame 应该会隐式产生浮点数组。如果您担心精度,则可以省略。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)