天天看點

(OpenCV+Python)--RGB轉HSI

cv2.cvtColor函數封裝了各種顔色空間之間的轉換,唯獨沒有RGB與HSI之間的轉換,網上查來查去也隻有C++或MATLAB版本的,自己要用到python裡,是以就寫寫python版本的。

HSI顔色模型是一個滿足計算機數字化顔色管理需要的高度抽象模拟的數學模型。HIS模型是從人的視覺系統出發,直接使用顔色三要素–色調(Hue)、飽和度(Saturation)和亮度(Intensity,有時也翻譯作密度或灰階)來描述顔色。

RGB向HSI模型的轉換是由一個基于笛卡爾直角坐标系的機關立方體向基于圓柱極坐标的雙錐體的轉換。基本要求是将RGB中的亮度因素分離,通常将色調和飽和度統稱為色度,用來表示顔色的類别與深淺程度。在圖中圓錐中間的橫截面圓就是色度圓,而圓錐向上或向下延伸的便是亮度分量的表示。

(OpenCV+Python)--RGB轉HSI

從RGB空間到HSI空間的轉換有多種方法,這裡僅說明最為經典的幾何推導法。RGB與HSI之間的轉換關系為:

(OpenCV+Python)--RGB轉HSI

下面直接上代碼:

import cv2
import numpy as np

def rgbtohsi(rgb_lwpImg):
    rows = int(rgb_lwpImg.shape[0])
    cols = int(rgb_lwpImg.shape[1])
    b, g, r = cv2.split(rgb_lwpImg)
    # 歸一化到[0,1]
    b = b / 255.0
    g = g / 255.0
    r = r / 255.0
    hsi_lwpImg = rgb_lwpImg.copy()
    H, S, I = cv2.split(hsi_lwpImg)
    for i in range(rows):
        for j in range(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 = 2*3.14169265 - 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/(2*3.14159265)
            I = sum/3.0
            # 輸出HSI圖像,擴充到255以友善顯示,一般H分量在[0,2pi]之間,S和I在[0,1]之間
            hsi_lwpImg[i, j, 0] = H*255
            hsi_lwpImg[i, j, 1] = S*255
            hsi_lwpImg[i, j, 2] = I*255
    return hsi_lwpImg
if __name__ == '__main__':
    rgb_lwpImg = cv2.imread("123.jpg")
    hsi_lwpImg = rgbtohsi(rgb_lwpImg)

    cv2.imshow('rgb_lwpImg', rgb_lwpImg)
    cv2.imshow('hsi_lwpImg', hsi_lwpImg)

    key = cv2.waitKey(0) & 0xFF
    if key == ord('q'):
        cv2.destroyAllWindows()


           
(OpenCV+Python)--RGB轉HSI