通过rgb转hsv再转回rgb后,发现cv2内置的三种转变方式存在精度上的损失差异。
import cv2
import numpy as np
image_path = './test.jpg'
image = cv2.imread(image_path)
# method 1
image_hsv_1 = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
image_hsv_1_bgr = cv2.cvtColor(image_hsv_1, cv2.COLOR_HSV2BGR) # h在0-180, s、v在0-255
cv2.imwrite('./method1.jpg', image_hsv_1_bgr)
# method 2
image_hsv_2 = cv2.cvtColor(image, cv2.COLOR_BGR2HSV_FULL) # h、s、v在0-255
image_hsv_2_bgr = cv2.cvtColor(image_hsv_2, cv2.COLOR_HSV2BGR_FULL)
cv2.imwrite('./method2.jpg', image_hsv_1_bgr)
# method 3
image_float = image / 255. # 先转变到0-1之间
image_float = image_float.astype('float32')
image_hsv_3 = cv2.cvtColor(image_float, cv2.COLOR_BGR2HSV) # h在0-360, s、v在0-1
image_hsv_3_bgr = cv2.cvtColor(image_hsv_1, cv2.COLOR_HSV2BGR)
image_hsv_3_bgr = np.uint8(np.clip(image_hsv_3_bgr*255, 0, 255))
cv2.imwrite('./method3.jpg', image_hsv_1_bgr)
记得之前看过一篇博客说这三种方式精度损失最大的就是method1,最小的是method3的float型转变。在底层代码中,前两种其实都是先变为float进行计算,只不过在输出时为了8-bit符合保存,而做了一些乘除。
在自己实践中,那种分辨率一般的普通场景其实不太看得处问题。我是在对比色阶卡上发现了异常,因为图像是自己拿设备采集的,还有可能原图就存在一些问题,通过这种转变加重了现象。
第一个是原图 ,右上是method1,左下是method3,左下是method2。可以看蓝色的色块。
这篇博文也说了这个情况,并用了一个很好的图来展示这个问题
https://stackoverflow.com/questions/54065840/python-cv2-color-space-conversion-fidelity-loss
所以在深度学习网络中使用hsv颜色域还是要小心一些!