【问题标题】:Python CV2 Color Space Conversion Fidelity LossPython CV2 颜色空间转换保真度损失
【发布时间】:2019-06-01 14:43:12
【问题描述】:

观察下图:

观察以下 Python 代码:

import cv2
img = cv2.imread("rainbow.png", cv2.IMREAD_COLOR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # convert it to hsv
img = cv2.cvtColor(img, cv2.COLOR_HSV2BGR) # convert back to BGR
cv2.imwrite("out.png", img)

这是输出图像:

如果您看不到它,则此处的图像明显失去了视觉保真度。为了比较起见,这里是输出图像旁边的原始图像,在黄色附近放大:

这里发生了什么?有什么方法可以防止出现这些块状伪影吗?我需要转换为 HSL 颜色空间来旋转色调,但如果我要得到这些类型的伪像,我就不能这样做。

请注意,当我不进行两次转换时,输出图像没有伪影;转换本身确实是原因。

【问题讨论】:

  • 可能是 8 位图像?色调从 360 度映射到 180 度以保持在 255 以下 - 无符号 8 位数字的限制。所以有一个 2 度的色调粒度。
  • @MarkSetchell,你是对的,它是一个 8 位图像。那么我该怎么做才能避免这种情况呢?
  • 我不在电脑前测试,但我会尝试使用 float 而不是 8 位。

标签: python image opencv colors cv2


【解决方案1】:

现在回到电脑前 - 试试这样:

#!/usr/bin/env python3
import numpy as np
import cv2

img = cv2.imread("rainbow.png", cv2.IMREAD_COLOR)
img = img.astype(np.float32)/255           # go to 32-bit float on 0..1

img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # convert it to hsv
img = cv2.cvtColor(img, cv2.COLOR_HSV2BGR) # convert back to BGR
cv2.imwrite("output.png", (img*255).astype(np.uint8))

我认为问题在于,当您使用无符号 8 位表示时,色调会从 0..360 的范围“挤压” 变为 0..180 的范围,在 2度数增量以保持在 0..255 的 8 位无符号范围内,从而导致附近值之间的步长。一种解决方案是移动到 32 位浮点数并缩放到 0..1 范围。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    相关资源
    最近更新 更多