使用 OpenImageIO 和 Python 将 sRGB 图像转换为灰度图像

问题描述

我无法在任何在线或文档中找到清楚解释如何使用 Python 进行此转换的任何地方。在我的情况下,我需要使用 OpenImageIO 来完成它——我只需要给它一个路径并保存转换后的图像,理想情况下输出单通道灰度图像会很棒。有谁知道怎么做?提前致谢!

解决方法

“平均”方法是错误的,因为您的眼睛并非对所有波长都敏感,因此 R、G 和 B 对您的亮度感知的贡献不同。这意味着您通过平均获得的灰度图像似乎与原始彩色图像的相对亮度不同。此外,sRGB 不是线性编码,因此编码值的“平均值”(或任何加权和)并不是您想象的那样。

使用 Python 中的 OpenImageIO 执行此操作的完全正确方法是:

import OpenImageIO as oiio
# Read the image,force it to be float for full precision
img = oiio.ImageBuf("input.jpg")
img.read(convert='float')
# linearize it -- this assumes sRGB,which jpeg always is
lin = oiio.ImageBufAlgo.colorconvert(img,"sRGB","linear")
# generate a luminance image with proper channel weights
luma = oiio.ImageBufAlgo.channel_sum (img,(.2126,.7152,.0722))
# convert back to sRGB for proper jpeg output
luma = oiio.ImageBufAlgo.colorconvert(luma,"linear","sRGB")
luma.write("luma.jpg")

如果您只是对从命令行(而不是 Python)执行此操作感兴趣,则非常简单:

oiiotool --autocc rgb.jpg --chsum:weight=.2126,.0722 -o luma.jpg

(autocc 在输入时自动线性化并在输出到 jpeg 时返回 sRGB)

请注意,在这两种情况下,您都在输出具有亮度的单通道图像。如果您确实需要将其转换为 R、G 和 B 均相等的 RGB 图像,则只需多加几行即可。