Python编程:ISP中色彩空间转换

色彩空间转换(Color Space Conversion)是图像处理中的基础操作,用于在不同颜色表示系统之间进行转换。下面介绍常见的色彩空间及其转换方法,并提供Python实现示例。

常见色彩空间概述

色彩空间 主要用途 通道组成 特点
RGB 显示器显示 红(R)、绿(G)、蓝(B) 设备相关,直观
HSV/HSL 颜色选择、分析 色调(H)、饱和度(S)、明度(V)/亮度(L) 更符合人类感知
LAB 颜色差异测量 明度(L)、a(红绿轴)、b(黄蓝轴) 设备无关,均匀色差
YUV/YCbCr 视频压缩 亮度(Y)、色度(UV/CbCr) 分离亮度和色度
CMYK 印刷 青(C)、品红(M)、黄(Y)、黑(K) 减色混合

Python基础转换方法

1. 使用OpenCV进行转换

import cv2
import numpy as np

# 读取图像(BGR格式)
img_bgr = cv2.imread('image.jpg')

# BGR转RGB
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

# BGR转HSV
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)

# BGR转LAB
img_lab = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2LAB)

# BGR转YCrCb
img_ycrcb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2YCrCb)

# 显示转换结果
def show_images(images, titles):
    for i, (img, title) in enumerate(zip(images, titles)):
        cv2.imshow(title, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

show_images(
    [img_bgr, img_rgb, img_hsv[:,:,0], img_lab[:,:,0]], 
    ['BGR', 'RGB', 'HSV-Hue', 'LAB-L']
)

2. 手动实现RGB转HSV

def rgb_to_hsv(rgb_img):
    """手动实现RGB到HSV转换"""
    img = rgb_img.astype('float32') / 255.0
    r, g, b = cv2.split(img)
    
    # 计算值(Value)
    v = np.maximum.reduce([r, g, b])
    
    # 计算饱和度(Saturation)
    min_val = np.minimum.reduce([r, g, b])
    delta = v - min_val
    s = np.where(v == 0, 0, delta / v)
    
    # 计算色调(Hue)
    h = np.zeros_like(v)
    mask = delta != 0
    
    # 红色为基准
    idx = (v == r) & mask
    h[idx] = (60 * ((g[idx] - b[idx]) / delta[idx]) + 360) % 360
    
    # 绿色为基准
    idx = (v == g) & mask
    h[idx] = (60 * ((b[idx] - r[idx]) / delta[idx]) + 120) % 360
    
    # 蓝色为基准
    idx = (v == b) & mask
    h[idx] = (60 * ((r[idx] - g[idx]) / delta[idx]) + 240) % 360
    
    # 归一化到OpenCV标准范围
    h = h / 2  # [0,180]
    s = s * 255  # [0,255]
    v = v * 255  # [0,255]
    
    return cv2.merge([h, s, v]).astype('uint8')

# 使用示例
hsv_manual = rgb_to_hsv(img_rgb)
hsv_opencv = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2HSV)

# 比较手动实现与OpenCV结果
print("差异:", np.sum(np.abs(hsv_manual - hsv_opencv)))

高级色彩空间转换

1. RGB与LAB的精确转换

def rgb_to_lab(rgb_img):
    """
    RGB转LAB色彩空间(精确实现)
    参考: http://www.easyrgb.com/en/math.php
    """
    # 转换为float32并归一化
    rgb = rgb_img.astype('float32') / 255.0
    
    # 线性化RGB(去除gamma校正)
    mask = rgb <= 0.04045
    rgb_linear = np.where(mask, rgb / 12.92, ((rgb + 0.055) / 1.055) ** 2.4)
    
    # 转换为XYZ色彩空间
    x = rgb_linear[...,0] * 0.4124 + rgb_linear[...,1] * 0.3576 + rgb_linear[...,2] * 0.1805
    y = rgb_linear[...,0] * 0.2126 + rgb_linear[...,1] * 0.7152 + rgb_linear[...,2] * 0.0722
    z = rgb_linear[...,0] * 0.0193 + rgb_linear[...,1] * 0.1192 + rgb_linear[...,2] * 0.9505
    
    # 归一化到白点D65
    x /= 0.95047
    y /= 1.0
    z /= 1.08883
    
    # 非线性变换
    epsilon = 216/24389
    kappa = 24389/27
    
    # 计算f(t)
    def f(t):
        return np.where(t > epsilon, t ** (1/3), (kappa * t + 16) / 116)
    
    fx = f(x)
    fy = f(y)
    fz = f(z)
    
    # 计算LAB
    l = 116 * fy - 16
    a = 500 * (fx - fy)
    b = 200 * (fy - fz)
    
    # 转换为OpenCV范围
    l = l * 255 / 100
    a = a + 128
    b = b + 128
    
    return cv2.merge([l, a, b]).astype('uint8')

# 使用示例
lab_manual = rgb_to_lab(img_rgb)
lab_opencv = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2LAB)

# 比较结果
print("L通道差异:", np.mean(np.abs(lab_manual[:,:,0] - lab_opencv[:,:,0])))

2. 色彩空间转换矩阵优化

def apply_color_matrix(img, matrix):
    """应用色彩转换矩阵"""
    # 重塑为(像素数, 3)
    orig_shape = img.shape
    pixels = img.reshape(-1, 3).astype('float32')
    
    # 添加齐次坐标
    pixels = np.hstack([pixels, np.ones((pixels.shape[0], 1))])
    
    # 应用矩阵变换
    transformed = np.dot(pixels, matrix.T)
  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值