图像RGB到HSV色彩空间转换及其逆变换
HSV 即使用 色相(Hue)、饱和度(Saturation)、明度(Value) 来表示色彩的一种方式
色相:将颜色用0°到360°表示,就是我们日常讲的颜色名称,如红色、蓝色等。
饱和度:色彩的纯度,饱和度越低色彩越暗淡(0<=S<1)
明度:即颜色的明亮程度,数值越高越接近于白色,数值越低越接近于黑色(0<=V<1)
将图像从RGB色彩空间转换到HSV色彩空间的算法如下所示:
Max = max(R,G,B)
Min = min(R,G,B)
饱和度: S = Max - Min
明度:V = Max
从HSV转换到RGB空间:
# 上 BGR2HSV 和 HSV2BGR 代码 import cv2 import numpy as np # BGR -> HSV def BGR2HSV(_img): img = _img.copy() / 255. hsv = np.zeros_like(img, dtype=np.float32) # get max and min max_v = np.max(img, axis=2).copy() min_v = np.min(img, axis=2).copy() min_arg = np.argmin(img, axis=2) # H hsv[..., 0][np.where(max_v == min_v)]= 0 ## if min == B ind = np.where(min_arg == 0) hsv[..., 0][ind] = 60 * (img[..., 1][ind] - img[..., 2][ind]) / (max_v[ind] - min_v[ind]) + 60 ## if min == R ind = np.where(min_arg == 2) hsv[..., 0][ind] = 60 * (img[..., 0][ind] - img[..., 1][ind]) / (max_v[ind] - min_v[ind]) + 180 ## if min == G ind = np.where(min_arg == 1) hsv[..., 0][ind] = 60 * (img[..., 2][ind] - img[..., 0][ind]) / (max_v[ind] - min_v[ind]) + 300 # S hsv[..., 1] = max_v.copy() - min_v.copy() # V hsv[..., 2] = max_v.copy() return hsv def HSV2BGR(_img, hsv): img = _img.copy() / 255. # get max and min max_v = np.max(img, axis=2).copy() min_v = np.min(img, axis=2).copy() out = np.zeros_like(img) H = hsv[..., 0] S = hsv[..., 1] V = hsv[..., 2] C = S H_ = H / 60. X = C * (1 - np.abs( H_ % 2 - 1)) Z = np.zeros_like(H) vals = [[Z,X,C], [Z,C,X], [X,C,Z], [C,X,Z], [C,Z,X], [X,Z,C]] for i in range(6): ind = np.where((i <= H_) & (H_ < (i+1))) out[..., 0][ind] = (V - C)[ind] + vals[i][0][ind] out[..., 1][ind] = (V - C)[ind] + vals[i][1][ind] out[..., 2][ind] = (V - C)[ind] + vals[i][2][ind] out[np.where(max_v == min_v)] = 0 out = np.clip(out, 0, 1) out = (out * 255).astype(np.uint8) return out
利用上述函数实现图像色相翻转(色相值+180,然后用 RGB色彩空间表示图片)
# Read image img = cv2.imread("../paojie.jpg").astype(np.float32) # RGB > HSV hsv = BGR2HSV(img) # Transpose Hue hsv[..., 0] = (hsv[..., 0] + 180) % 360 # HSV > RGB out = HSV2BGR(img, hsv) # Save result cv2.imwrite("out.jpg", out) cv2.imshow("result", out) cv2.waitKey(0) cv2.destroyAllWindows()
原图