Python CV2颜色空间转换保真度损失

时间:2019-01-06 20:51:29

标签: python image opencv colors cv2

观察下图:

enter image description here

观察以下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)

这是输出图像:

enter image description here

如果看不到,这里的图像将明显失去视觉保真度。为了进行比较,下面是输出图像旁边的原图,放大了黄色部分:

enter image description here

这是怎么回事?有什么方法可以防止这些块状伪像出现?我需要转换为HSL颜色空间以旋转色调,但是如果要获取这些工件,则无法这样做。

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

1 个答案:

答案 0 :(得分: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的范围变为“压扁” ,范围为2的0..180。度增量以保持在0..255的8位无符号范围内,从而导致附近值之间出现阶跃。一种解决方案是移至32位浮点数,并缩放至0..1。范围。