Color Models (RGB, CMY, HSI)

Gonzalez R. C. and Woods R. E. Digital Image Processing (Forth Edition)

除了我们熟悉的RGB模式来表示图片, 还有其他很多种图片表示方式. 其实我现在很想要知道的一点是, 神经网络会对不同的表示会有不同的反应吗?

定义

RGB

普通的彩色图片, 每个像素点是一个三维的值 ( x , y , z ) ∈ [ 0 , 1 ] 3 (x, y, z) \in [0, 1]^3 (x,y,z)[0,1]3,

CMY

RGB是以Red, Green, Blue为坐标轴的坐标系, 而CMY是以Cyan, Magenta, Yellow为坐标轴(这些颜色成为second colors), 以White为原点的坐标系.

CMYK

CMY因为不是以black为原点, 所以在实际中难以表示true black? 所以特意引入第四个颜色K表示黑色.

HSI

HSI, 即hue, saturation, identisity.

Hue: 即表示某种颜色, 正如上图所示, 以H, 点与红色(标准)之间的角度(相当于指定某种颜色).

Saturation: 饱和度, 顾名思义, 表示该颜色是有多少的纯色和白色混合在一起的.

Identisity: 灰度值, 将一个图像变成一个灰度图就是根据这个指标, 其相当于 ( x , y , z ) (x, y, z) (x,y,z)在black-white这个轴上的投影.

注: HSI的值也是归一化为 [ 0 , 1 ] [0, 1] [0,1]之间.

相互的转换

RGB <=> CMY

[ C M Y ] = [ 1 1 1 ] − [ R G B ] . \left [ \begin{array}{l} C \\ M \\ Y \\ \end{array} \right ] = \left [ \begin{array}{l} 1 \\ 1 \\ 1 \\ \end{array} \right ] - \left [ \begin{array}{l} R \\ G \\ B \end{array} \right ] . CMY=111RGB.

CMY <=> CMYK

CMY > CMYK

K = min ⁡ ( C , M , Y ) , C = ( C − K ) / ( 1 − K ) , M = ( M − K ) / ( 1 − K ) , Y = ( Y − K ) / ( 1 − K ) . K = \min (C, M, Y), \\ C = (C - K) / (1 - K), \\ M = (M - K) / (1 - K), \\ Y = (Y - K) / (1 - K). \\ K=min(C,M,Y),C=(CK)/(1K),M=(MK)/(1K),Y=(YK)/(1K).

CMYK > CMY

C = C ∗ ( 1 − K ) + K , M = M ∗ ( 1 − K ) + K , Y = Y ∗ ( 1 − K ) + K . C = C * (1 - K) + K, \\ M = M * (1 - K) + K, \\ Y = Y * (1 - K) + K. \\ C=C(1K)+K,M=M(1K)+K,Y=Y(1K)+K.

RGB <=> HSI

hsi-to-rgb-conversion.pdf (tau.ac.il)

RGB > HSI

注意RGB > HSI并非直接的坐标变换, 具体的推导可以看上面的参考文献.

θ = cos ⁡ − 1 { 1 2 [ ( R − G ) + ( R − B ) ] [ ( R − G ) 2 + ( R − B ) ( G − B ) ] 1 / 2 } , H = { θ / 2 π if   B ≤ G , 1 − θ / 2 π if   B > G . S = 1 − 3 R + G + B [ min ⁡ ( R , G , B ) ] . I = 1 3 ( R + G + B ) . \theta = \cos^{-1} \{ \frac{\frac{1}{2}[(R-G) + (R-B)]}{[(R-G)^2 + (R-B)(G-B)]^{1/2}} \}, \\ H = \left \{ \begin{array}{ll} \theta / 2\pi & \text{if} \: B \le G, \\ 1 - \theta/2\pi & \text{if} \: B > G. \end{array} \right . \\ S = 1 - \frac{3}{R + G + B}[\min (R, G, B)]. \\ I = \frac{1}{3}(R + G + B). θ=cos1{[(RG)2+(RB)(GB)]1/221[(RG)+(RB)]},H={θ/2π1θ/2πifBG,ifB>G.S=1R+G+B3[min(R,G,B)].I=31(R+G+B).

注: 原文使用的是角度制, 这里我改成弧度制, 另外我这里直接将 H H H归一化了.

HSI > RGB

HSI > RGB 需要根据 H H H的不同改变策略:

首先令 H = H ⋅ 2 π ∈ [ 0 , 2 π ) H = H \cdot 2\pi \in [0, 2\pi) H=H2π[0,2π).

  1. H ∈ [ 0 , 2 3 π ] H \in [0, \frac{2}{3}\pi] H[0,32π]:

B = I ( 1 − S ) , R = I [ 1 + S cos ⁡ H cos ⁡ ( 1 3 π − H ) ] , G = 3 I − ( R + B ) . B = I(1-S), \\ R = I[1 + \frac{S\cos H}{\cos (\frac{1}{3}\pi - H)}], \\ G = 3I - (R + B). B=I(1S),R=I[1+cos(31πH)ScosH],G=3I(R+B).

  1. H ∈ [ 2 3 π , 4 3 π ) H \in [\frac{2}{3}\pi, \frac{4}{3}\pi) H[32π,34π):

H = H − 2 3 π , R = I ( 1 − S ) , G = I [ 1 + S cos ⁡ H cos ⁡ ( 1 3 π − H ) ] , B = 3 I − ( R + G ) . H = H - \frac{2}{3}\pi, \\ R = I(1-S), \\ G = I[1 + \frac{S\cos H}{\cos (\frac{1}{3}\pi - H)}], \\ B = 3I - (R + G). H=H32π,R=I(1S),G=I[1+cos(31πH)ScosH],B=3I(R+G).

  1. H ∈ [ 4 3 π , 2 π ) H \in [\frac{4}{3}\pi, 2\pi) H[34π,2π):

H = H − 4 3 π , G = I ( 1 − S ) , B = I [ 1 + S cos ⁡ H cos ⁡ ( 1 3 π − H ) ] , R = 3 I − ( G + B ) . H = H - \frac{4}{3}\pi, \\ G = I(1-S), \\ B = I[1 + \frac{S\cos H}{\cos (\frac{1}{3}\pi - H)}], \\ R = 3I - (G + B). H=H34π,G=I(1S),B=I[1+cos(31πH)ScosH],R=3I(G+B).

代码示例

import cv2
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
img = np.random.randint(0, 256, (10, 10, 3), dtype=np.uint8)
# rgb -> hsi
def calcH(v):
    r, g, b = v
    val = (2 * r - g - b) / np.sqrt((r - g) ** 2 + (r - b) * (g - b))
    val /= 2
    theta = np.arccos(val)
    h = theta / (2 * np.pi) if b <= g else (1 - theta / (2 * np.pi))
    return h

def calcS(v):
    return 1 - 3 * v.min() / v.sum()

def calcI(v):
    return v.mean()

def rgb2hsi(img: np.ndarray) -> np.ndarray:
    img = img.astype(np.float) / 255.
    def unit(v):
        h = calcH(v)
        s = calcS(v)
        i = calcI(v)
        return np.array([h, s, i])
    img = np.apply_along_axis(unit, 2, img)
    return img
# hsi -> rgb

def unit(v):
    h, s, i = v
    idx = np.arange(3)
    h = h * np.pi * 2
    if h >= 2 * np.pi / 3:
        if h >= 4 * np.pi / 3:
            h = h - 4 * np.pi / 3
            idx = (idx - 2) % 3
        else:
            h = h - 2 * np.pi / 3
            idx = (idx - 1) % 3
    b = i * (1 - s)
    r = i * (1 + s * np.cos(h) / np.cos(np.pi / 3 - h))
    g = 3 * i - b - r
    v = np.array([r, g, b])
    return v[idx]



def hsi2rgb(img: np.ndarray):
    img = img.astype(np.float) / 255.
    img = np.apply_along_axis(unit, 2, img) * 255
    return img.astype(np.uint8)

在opencv库中, 可以通过如下手段变化:

rgb2hsi_cv = cv2.cvtColor(img[..., [2, 1, 0]], cv2.COLOR_BGR2HLS)
hsi2rgb_cv = cv2.cvtColor(rgb2hsi_cv, cv2.COLOR_HLS2BGR)[..., [2, 1, 0]]

opencv采用BGR格式是由于历史原因.

另外, 其出来的结果和我所实现的结果并不一致, 其I值也并非 1 3 ( R + G + B ) \frac{1}{3}(R + G + B) 31(R+G+B)​, 所以我怀疑可能用的是另外一套变换公式(虽然网上说, HLS就是HSI).

在PIL库中, 我没找到RGB2HSI的函数, 不过PIL一般采用如下方式进行变换:

rgb2what = Image.fromarray(img).convert('RGB').convert('...')

注: '…'部分表示mode, 具体参考: Concepts — Pillow (PIL Fork) 8.3.1 documentation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值