如何使用 scikit-image and/or PIL 将 ProPhoto RGB 色彩空间转换为 RGB?
How do you convert ProPhoto RGB colorspace to RGB with scikit-image and/or PIL?
我有 ProPhoto RGB 颜色的 TIF 文件space。这些是使用 scikit-image 的“imload”方法导入的。但是,当我尝试使用 matplotlib 查看图像数据时,我收到错误消息:
plt.imshow(myImage)
plt.show()
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
值被裁剪为 255 并显示全白图像。 imread 读取的图像数据的错误是正确的。值如下所示:
myImage[0]
array([[60061, 60135, 60673],
[59907, 59983, 60533],
[59931, 60007, 60557],
...,
[60649, 60801, 61147],
[60581, 60743, 61091],
[60647, 60797, 61143]], dtype=uint16)
显然需要缩放这些值以获得介于 0-255 之间的正确 RGB 值。
当我在 IrfanView 之类的工具中打开图像文件并重新保存时,颜色space 被正确处理为 RGB(可能是因为 IrfanView 正在为我转换它)。但是,我需要自动进行该转换。
是否可以使用 scikit-image 或 PIL(或其他)将使用 ProPhoto RGB 颜色space 的 TIF 转换为 RGB 颜色space?在 https://scikit-image.org/docs/stable/api/skimage.color.html 的 scikit-image 的“颜色”模块的文档中,我没有看到任何提及该颜色的内容 space。除非“ProPhoto RGB”可以换个名字或与其他转换方法兼容?
谢谢!
编辑:
用户 Abhi25t 的回答有助于在显示这些图像方面取得一些进展。然而,他们的回答似乎只针对 16 位到 8 位的转换。 ProPhoto RGB 到 sRGB 仍然存在 colorspace 问题。希望这次编辑能更好地展示这一点。
ProPhoto 颜色中原始测试 TIF 图像的像素值space:
array([[58465, 58479, 58785],
[58575, 58591, 58879],
[58441, 58457, 58739],
...,
[58185, 58045, 58549],
[58101, 57951, 58463],
[57993, 57853, 58371]], dtype=uint16)
Photoshop sRGB 转换文件的像素值:
array([[59771, 59873, 60161],
[59863, 59965, 60235],
[59755, 59855, 60119],
...,
[59623, 59489, 59993],
[59561, 59411, 59925],
[59463, 59333, 59851]], dtype=uint16)
IRFAN VIEW 转换文件的像素值(它似乎已转换为 8 位并转换为 sRGB space):
array([[233, 233, 234],
[233, 233, 234],
[232, 233, 234],
...,
[232, 231, 233],
[232, 231, 233],
[231, 231, 233]], dtype=uint8)
我在这里添加了一些测试代码和图片:
https://drive.google.com/drive/folders/1tcfUY2Kwlz-LAlt6_YXtT8l6vLnCucbM?usp=sharing
图像应显示为颜色检查器目标。您应该能够正确地看到它,只需绘制“TEST_PROPHOTO_IRFAN_SAVED.tif”的 imread 结果。
from skimage import io
import numpy as np
import matplotlib.pyplot as plt
# TEST_PROPHOTO.tif : RAW TIF FILE
# TEST_PROPHOTO_IRFAN_SAVED.tif : RAW TIF, OPENED IN IRFANVIEW AND RESAVED AS TIF
# TEST_SRGB_PHOTOSHOP_CONVERTED.tif : RAW TIF, OPENED IN PHOTOSHOP, PROFILE CONVERTED TO sRGB, RESAVED AS TIF
img_path = '/path/to/image/myImage.tif'
img_rgb = io.imread(img_path)
plt.imshow(img_rgb)
plt.show()
# VIEW IMAGE CONTENTS
img_rgb[0] # you can see these values are 16-bit;
# however, colorspace (actual RGB values) differs between the ProPhoto test file and the Photoshop converted sRGB file
# Whosebug USER Abhi25t's METHOD TO CONVERT FROM 16-bit color [0-65535] to 8-bit color [0-255]:
img_rgb_convert = img_rgb * (255/65535)
img_rgb_convert = img_rgb_convert.astype(int)
plt.imshow(img_rgb_convert)
plt.show()
您需要在此处将 16 位分辨率(灰度)转换为 8 位。
myImage = myImage * 255/65535
然后matplotlib就可以显示了
如果需要,将您的浮点数转换为整数。
myImage = myImage.astype(int)
您需要执行以下步骤:
- 用
imread
读取图像。
- 转换为[0-1]范围内的浮点数表示,即转换为浮点数并除以65535。
- 使用RIMM-ROMM RGB decoding function解码。
- 使用 required colour conversion matrix:
从 RIMM-ROMM RGB 色域转换为 sRGB 色域
# Using CAT02.
[[ 2.0364917242 -0.7375906525 -0.2992598689]
[-0.2257179791 1.2231765313 0.0027252248]
[-0.0105451286 -0.1348798497 1.1452101525]]
- 编码为 sRGB inverse Electro-Optical Transfer Function。
- 转换为 [0-255] 范围内的整数表示,即乘以 255 并转换为整数。
Colour can do 3 to 5 directly using the colour.RGB_to_RGB定义。假设数据已经在浮点范围内,转换将是这样的:
img_rgb_convert = colour.RGB_to_RGB(
img_rgb,
colour.RGB_COLOURSPACES['ProPhoto RGB'],
colour.RGB_COLOURSPACES['sRGB'],
chromatic_adaptation_transform='CAT02',
apply_cctf_decoding=True,
apply_cctf_encoding=True)
注意:由于ProPhoto RGB的色域比sRGB的色域大,转换后可能会产生色差色域颜色,为了简单起见,在步骤 4 或 5 之后可以将这些颜色剪裁在 [0-1] 范围内,或者使用专用算法进行色域映射。
我有 ProPhoto RGB 颜色的 TIF 文件space。这些是使用 scikit-image 的“imload”方法导入的。但是,当我尝试使用 matplotlib 查看图像数据时,我收到错误消息:
plt.imshow(myImage)
plt.show()
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
值被裁剪为 255 并显示全白图像。 imread 读取的图像数据的错误是正确的。值如下所示:
myImage[0]
array([[60061, 60135, 60673],
[59907, 59983, 60533],
[59931, 60007, 60557],
...,
[60649, 60801, 61147],
[60581, 60743, 61091],
[60647, 60797, 61143]], dtype=uint16)
显然需要缩放这些值以获得介于 0-255 之间的正确 RGB 值。
当我在 IrfanView 之类的工具中打开图像文件并重新保存时,颜色space 被正确处理为 RGB(可能是因为 IrfanView 正在为我转换它)。但是,我需要自动进行该转换。
是否可以使用 scikit-image 或 PIL(或其他)将使用 ProPhoto RGB 颜色space 的 TIF 转换为 RGB 颜色space?在 https://scikit-image.org/docs/stable/api/skimage.color.html 的 scikit-image 的“颜色”模块的文档中,我没有看到任何提及该颜色的内容 space。除非“ProPhoto RGB”可以换个名字或与其他转换方法兼容?
谢谢!
编辑:
用户 Abhi25t 的回答有助于在显示这些图像方面取得一些进展。然而,他们的回答似乎只针对 16 位到 8 位的转换。 ProPhoto RGB 到 sRGB 仍然存在 colorspace 问题。希望这次编辑能更好地展示这一点。
ProPhoto 颜色中原始测试 TIF 图像的像素值space:
array([[58465, 58479, 58785],
[58575, 58591, 58879],
[58441, 58457, 58739],
...,
[58185, 58045, 58549],
[58101, 57951, 58463],
[57993, 57853, 58371]], dtype=uint16)
Photoshop sRGB 转换文件的像素值:
array([[59771, 59873, 60161],
[59863, 59965, 60235],
[59755, 59855, 60119],
...,
[59623, 59489, 59993],
[59561, 59411, 59925],
[59463, 59333, 59851]], dtype=uint16)
IRFAN VIEW 转换文件的像素值(它似乎已转换为 8 位并转换为 sRGB space):
array([[233, 233, 234],
[233, 233, 234],
[232, 233, 234],
...,
[232, 231, 233],
[232, 231, 233],
[231, 231, 233]], dtype=uint8)
我在这里添加了一些测试代码和图片: https://drive.google.com/drive/folders/1tcfUY2Kwlz-LAlt6_YXtT8l6vLnCucbM?usp=sharing
图像应显示为颜色检查器目标。您应该能够正确地看到它,只需绘制“TEST_PROPHOTO_IRFAN_SAVED.tif”的 imread 结果。
from skimage import io
import numpy as np
import matplotlib.pyplot as plt
# TEST_PROPHOTO.tif : RAW TIF FILE
# TEST_PROPHOTO_IRFAN_SAVED.tif : RAW TIF, OPENED IN IRFANVIEW AND RESAVED AS TIF
# TEST_SRGB_PHOTOSHOP_CONVERTED.tif : RAW TIF, OPENED IN PHOTOSHOP, PROFILE CONVERTED TO sRGB, RESAVED AS TIF
img_path = '/path/to/image/myImage.tif'
img_rgb = io.imread(img_path)
plt.imshow(img_rgb)
plt.show()
# VIEW IMAGE CONTENTS
img_rgb[0] # you can see these values are 16-bit;
# however, colorspace (actual RGB values) differs between the ProPhoto test file and the Photoshop converted sRGB file
# Whosebug USER Abhi25t's METHOD TO CONVERT FROM 16-bit color [0-65535] to 8-bit color [0-255]:
img_rgb_convert = img_rgb * (255/65535)
img_rgb_convert = img_rgb_convert.astype(int)
plt.imshow(img_rgb_convert)
plt.show()
您需要在此处将 16 位分辨率(灰度)转换为 8 位。
myImage = myImage * 255/65535
然后matplotlib就可以显示了
如果需要,将您的浮点数转换为整数。
myImage = myImage.astype(int)
您需要执行以下步骤:
- 用
imread
读取图像。 - 转换为[0-1]范围内的浮点数表示,即转换为浮点数并除以65535。
- 使用RIMM-ROMM RGB decoding function解码。
- 使用 required colour conversion matrix: 从 RIMM-ROMM RGB 色域转换为 sRGB 色域
# Using CAT02.
[[ 2.0364917242 -0.7375906525 -0.2992598689]
[-0.2257179791 1.2231765313 0.0027252248]
[-0.0105451286 -0.1348798497 1.1452101525]]
- 编码为 sRGB inverse Electro-Optical Transfer Function。
- 转换为 [0-255] 范围内的整数表示,即乘以 255 并转换为整数。
Colour can do 3 to 5 directly using the colour.RGB_to_RGB定义。假设数据已经在浮点范围内,转换将是这样的:
img_rgb_convert = colour.RGB_to_RGB(
img_rgb,
colour.RGB_COLOURSPACES['ProPhoto RGB'],
colour.RGB_COLOURSPACES['sRGB'],
chromatic_adaptation_transform='CAT02',
apply_cctf_decoding=True,
apply_cctf_encoding=True)
注意:由于ProPhoto RGB的色域比sRGB的色域大,转换后可能会产生色差色域颜色,为了简单起见,在步骤 4 或 5 之后可以将这些颜色剪裁在 [0-1] 范围内,或者使用专用算法进行色域映射。