颜色空间的转换
CMY 空间
CMY 颜色空间正好与 RGB 颜色空间互补, 即用白色减去 RGB 颜色空间中的某一颜色值就等于这种颜色在 CMY 颜色空间中的值。
{ C = 1 − R M = 1 − G Y = 1 − B \begin{cases}C=1-R\\M=1-G\\Y=1-B\end{cases} ⎩ ⎨ ⎧C=1−RM=1−GY=1−B
HSV 空间
HSI/ HSV 颜色空间模型是从人的视觉系统出发, 用 H (Hue)、 S(Saturation)、 I(Intensity) 或 V(Value) 分别代表色调、 色饱和度、 亮度三种独立的颜色特征。
对于[0,1]的 R、G、B 值,HSV 各个分量计算如下
V = R + G + B 3 V=\frac{R+G+B}{3} V=3R+G+B
S = 1 − 3 R + G + B min ( R , G , B ) S=1-\frac{3}{R+G+B}\min(R,G,B) S=1−R+G+B3min(R,G,B)
H = { θ , B ≤ G 36 0 ∘ − θ , B > G H=\begin{cases}\theta,&B\le G\\360^\circ-\theta,&B>G\end{cases} H={θ,360∘−θ,B≤GB>G
其中
θ = arccos { ( R − G ) + ( R − B ) 2 [ ( R − G ) 2 + ( R − B ) ( G − B ) ] 1 2 } \theta=\arccos\left\{\frac{(R-G)+(R-B)}{2\Big[(R-G)^2+(R-B)(G-B)\Big]^{\frac{1}{2}}}\right\} θ=arccos⎩ ⎨ ⎧2[(R−G)2+(R−B)(G−B)]21(R−G)+(R−B)⎭ ⎬ ⎫
YCbCr 空间
YCbCr 颜色空间采用一个亮度信号 (Y) 和两个色差信号 (Cb , Cr ) 来表示。
对于[0,1]的 R、G、B,Y、Cr、Cb 计算如下:
[ Y C r C b ] = [ 0.2990 0.5870 0.1140 0.5000 − 0.4187 − 0.0813 − 0.1687 − 0.3313 0.5000 ] [ R G B ] + [ 6 128 128 ] \begin{bmatrix}Y\\C_\mathrm{r}\\C_\mathrm{b}\end{bmatrix}=\begin{bmatrix}0.2990&0.5870&0.1140\\0.5000&-0.4187&-0.0813\\-0.1687&-0.3313&0.5000\end{bmatrix}\begin{bmatrix}R\\G\\B\end{bmatrix}+\begin{bmatrix}6\\128\\128\end{bmatrix} YCrCb = 0.29900.5000−0.16870.5870−0.4187−0.33130.1140−0.08130.5000 RGB + 6128128
import cv2
import numpy as np
import matplotlib.pyplot as pltdef read_show_image(img, flag=0):img = np.squeeze(img)if np.ndim(img) == 2:plt.imshow(img, 'gray'), plt.title('灰度图'), plt.xticks([]), plt.yticks([])plt.show()elif np.ndim(img) == 3:R = img[..., 0]G = img[..., 1]B = img[..., 2]if flag == 1:plt.subplot(221), plt.imshow(img, 'gray'), plt.title('彩色图'), plt.xticks([]), plt.yticks([])plt.subplot(222), plt.imshow(R, 'gray'), plt.title('通道1'), plt.xticks([]), plt.yticks([])plt.subplot(223), plt.imshow(G, 'gray'), plt.title('通道2'), plt.xticks([]), plt.yticks([])plt.subplot(224), plt.imshow(B, 'gray'), plt.title('通道3'), plt.xticks([]), plt.yticks([])plt.show()else:zeros = np.zeros(img.shape[:2], dtype='uint8')plt.subplot(221), plt.imshow(img), plt.title('彩色图'), plt.xticks([]), plt.yticks([])plt.subplot(222), plt.imshow(cv2.merge([R, zeros, zeros])), plt.title('通道1'), plt.xticks([]), plt.yticks([])plt.subplot(223), plt.imshow(cv2.merge([zeros, G, zeros])), plt.title('通道2'), plt.xticks([]), plt.yticks([])plt.subplot(224), plt.imshow(cv2.merge([zeros, zeros, B])), plt.title('通道3'), plt.xticks([]), plt.yticks([])plt.show()else:print('Input error')def RGB2CMY(img):'''青 (Cyan)、 品红(Magenta) 和黄 (Yellow)'''r, g, b = cv2.split(img) # split the channels# normalization [0,1]r = r / 255.0g = g / 255.0b = b / 255.0c = 1 - rm = 1 - gy = 1 - bresult = cv2.merge((c, m, y))* 255 # merge the channelsreturn np.array(result).astype(np.uint8)def RGB2HSV(rgb_Img):''' 用 H(Hue)、 S(Saturation)、 I(Intensity) 或 V(Value) 分别代表色调、 色饱和度、 亮度'''img_rows = int(rgb_Img.shape[0])img_cols = int(rgb_Img.shape[1])b, g, r = cv2.split(rgb_Img)# normalization[0,1]r = r / 255.0g = g / 255.0b = b / 255.0hsv_Img = rgb_Img.copy()for i in range(img_rows):for j in range(img_cols):num = 0.5 * ((r[i, j] - g[i, j]) + (r[i, j] - b[i, j]))den = np.sqrt((r[i, j] - g[i, j]) ** 2 + (r[i, j] - b[i, j]) * (g[i, j] - b[i, j]))theta = float(np.arccos(num / den))if den == 0:H = 0elif b[i, j] <= g[i, j]:H = thetaelse:H = np.pi - thetamin_RGB = min(min(b[i, j], g[i, j]), r[i, j])sum = b[i, j] + g[i, j] + r[i, j]if sum == 0:S = 0else:S = 1 - 3 * min_RGB / sumH = H / (np.pi)V = sum / 3.0# 输出HSI图像,扩充到255以方便显示,一般H分量在[0,2pi]之间,S和I在[0,1]之间hsv_Img[i, j, 0] = H * 255hsv_Img[i, j, 1] = S * 255hsv_Img[i, j, 2] = V * 255return hsv_Imgdef RGB2YCbCr(rgb_image):"""Y:亮度 Cb:色差 Cr:色差"""if len(rgb_image.shape) != 3 or rgb_image.shape[2] != 3:raise ValueError("input image is not a rgb image")rgb_image = rgb_image.astype(np.float32)transform_matrix = np.array([[0.299, 0.587, 0.114],[0.5, 0.4187, -0.0813],[-0.1687, -0.3313, 0.5]])shift_matrix = np.array([16, 128, 128])ycbcr_image = np.zeros(shape=rgb_image.shape)w, h, _ = rgb_image.shapefor i in range(w):for j in range(h):ycbcr_image[i, j, :] = np.dot(transform_matrix, rgb_image[i, j, :]) + shift_matrixreturn np.array(ycbcr_image).astype(np.uint8)if __name__ == '__main__':lena = cv2.imread('lena_std.bmp')lena = np.array(lena)[..., ::-1]cmy = RGB2CMY(lena)hsv = RGB2HSV(lena)ycbcr = RGB2YCbCr(lena)plt.figure('RGB')read_show_image(lena)plt.figure('cmy')read_show_image(cmy)plt.figure('hsv')read_show_image(hsv,flag=1)plt.figure('ycbcr')read_show_image(ycbcr,flag=1)
参考:
https://cloud.tencent.com/developer/article/1784017