【数字图像处理】颜色空间的转换

本文详细介绍了颜色空间转换,包括CMY与RGB的关系,HSV色彩模型的定义,以及YCbCr色彩空间的表示方法。通过Python示例展示了如何将RGB图像转换为CMY、HSV和YCbCr格式。
摘要由CSDN通过智能技术生成

颜色空间的转换

在这里插入图片描述

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=1RM=1GY=1B

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=1R+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θ,BGB>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[(RG)2+(RB)(GB)]21(RG)+(RB)

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.50000.16870.58700.41870.33130.11400.08130.5000 RGB + 6128128


import cv2
import numpy as np
import matplotlib.pyplot as plt


def 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.0
    g = g / 255.0
    b = b / 255.0
    c = 1 - r
    m = 1 - g
    y = 1 - b
    result = cv2.merge((c, m, y))* 255  # merge the channels
    return 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.0
    g = g / 255.0
    b = b / 255.0
    hsv_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 = 0
            elif b[i, j] <= g[i, j]:
                H = theta
            else:
                H = np.pi - theta

            min_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 = 0
            else:
                S = 1 - 3 * min_RGB / sum
            H = H / (np.pi)
            V = sum / 3.0
            # 输出HSI图像,扩充到255以方便显示,一般H分量在[0,2pi]之间,S和I在[0,1]之间
            hsv_Img[i, j, 0] = H * 255
            hsv_Img[i, j, 1] = S * 255
            hsv_Img[i, j, 2] = V * 255
    return hsv_Img


def 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.shape
    for i in range(w):
        for j in range(h):
            ycbcr_image[i, j, :] = np.dot(transform_matrix, rgb_image[i, j, :]) + shift_matrix
    return 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二进制人工智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值