1. 程式人生 > >RGB色彩空間和HSV色彩空間的理解

RGB色彩空間和HSV色彩空間的理解

pretty avi ber 用途 fill 什麽 窗口 透明度 空間

轉自:https://blog.csdn.net/u010429424/article/details/76577399

本文的結構如下:
1、RGB色彩空間
2、HSV色彩空間(附HSV顏色分量範圍表)
3、RGB到HSV的轉換的Demo
??使用OpenCV實現RGB轉HSV,並通過滑動條動態設定HSV閾值
??自己寫程序,實現RGB轉HSL

1、RGB色彩空間

RGB色彩空間源於使用陰極射線管的彩色電視,RGB分別代表三個基色(R-紅色、G-綠色、B-藍色),具體的色彩值由三個基色疊加而成。在圖像處理中,我們往往使用向量表示色彩的值,如(0,0,0)表示黑色、(255, 255, 255)表示白色。其中,255表示色彩空間被量化成255個數,最高亮度值為255(255 = 2^8 - 1,即每個色彩通道用8位表示)。在這個色彩空間中,有256*256*256種顏色。RGB色彩空間如下圖所示(圖片來自百度百科)。是一個包含Red、Green、Blue的三維空間。

技術分享圖片

註:
1、在OpenCV中,RGB色彩空間的順序是BGR,千萬不要弄錯了
2、在Java的Bitmap中,RGB色彩空間被表示為ARGB,其中A代表透明度

2、HSV色彩空間

HSV色彩空間(Hue-色調、Saturation-飽和度、Value-值)將亮度從色彩中分解出來,在圖像增強算法中用途很廣。在我本人接觸的圖像處理項目中,經常將圖像從RGB色彩空間轉換到了HSV色彩空間,以便更好地感知圖像顏色,利用HSV分量從圖像中提取感興趣的區域。

HSV色彩空間也被稱為HSB(色調、飽和度、亮度),在PS中常被用到。

HSV色彩空間如下圖所示,用一個倒圓錐體表示整個色彩空間:

技術分享圖片

註:
1、H的範圍是[0,360),S和V的範圍是[0,1]。但是在OpenCV 中,HSV好像被規範化到了[0, 255],此處求大神指導。
2、另外,網上有人總結了HSV顏色對應RGB的分量範圍,見下面的表格。參考自:
http://www.cnblogs.com/wangyblzu/p/5710715.html
http://blog.csdn.net/taily_duan/article/details/51506776

技術分享圖片

3、RGB到HSV的轉換的Demo

(1) 使用OpenCV的cv2.cvtColor(src, cv2.COLOR_BGR2HSV)

OpenCV為我們提供了現成的函數cvtColor(),幫助我們將圖像從BGR轉換到HSV。

# -*- coding:utf-8 -*-

import cv2

"""
功能:讀取一張圖片,顯示出來,並轉化為HSV色彩空間
"""
image = cv2.imread(‘images/my_wife2.jpg‘) # 根據路徑讀取一張圖片
cv2.imshow("BGR", image) # 顯示圖片


# 轉化圖片到HSV色彩空間
dst = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow("HSV", dst) # 顯示圖片
cv2.waitKey(0) # 等待鍵盤觸發事件,釋放窗口

結果如下:

技術分享圖片

挺好看的美女,結果被弄成了這個樣子。一些初學者包括我自己有時會問,為什麽要把好端端的圖片轉成HSV色彩空間呢。其實這樣做大有用處,比如我們要提取美女的頭發區域,就可以通過設置HSV色彩空間的高低閾值來做。

# -*- coding:utf-8 -*-

import cv2
import numpy as np   # ------------------改變1

"""
功能:讀取一張圖片,顯示出來,並轉化為HSV色彩空間
"""
image = cv2.imread(‘images/my_wife2.jpg‘) # 根據路徑讀取一張圖片
cv2.imshow("BGR", image) # 顯示圖片


# 轉化圖片到HSV色彩空間
dst = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow("HSV", dst) # 顯示圖片


# 根據HSV提取頭發 --------------------------------改變2
low_hsv = np.array([0, 0, 46])
high_hsv = np.array([200, 40, 220])
dst = cv2.inRange(dst, low_hsv, high_hsv)
cv2.imshow("result", dst) # 顯示圖片

cv2.waitKey(0) # 等待鍵盤觸發事件,釋放窗口

程序的運行效果如下。我們看到,頭發區域顯示為白色,這樣我們就初步地提取出了頭發區域。當然這個效果並不理想,是因為我們設定的閾值不好,如果能動態地設定閾值就好了。

技術分享圖片

我們可以利用滑塊動態地設置閾值,一邊拖動滑塊,一邊觀察圖像。OpenCV提供了createTrackbar(),用於創建滑塊。代碼如下:

# -*- coding:utf-8 -*-

import cv2
import numpy as np

"""
功能:讀取一張圖片,顯示出來,轉化為HSV色彩空間
     並通過滑塊調節HSV閾值,實時顯示
"""

image = cv2.imread(‘images/my_wife2.jpg‘) # 根據路徑讀取一張圖片
cv2.imshow("BGR", image) # 顯示圖片

hsv_low = np.array([0, 0, 0])
hsv_high = np.array([0, 0, 0])

# 下面幾個函數,寫得有點冗余

def h_low(value):
    hsv_low[0] = value

def h_high(value):
    hsv_high[0] = value

def s_low(value):
    hsv_low[1] = value

def s_high(value):
    hsv_high[1] = value

def v_low(value):
    hsv_low[2] = value

def v_high(value):
    hsv_high[2] = value

cv2.namedWindow(‘image‘)
cv2.createTrackbar(‘H low‘, ‘image‘, 0, 255, h_low) 
cv2.createTrackbar(‘H high‘, ‘image‘, 0, 255, h_high)
cv2.createTrackbar(‘S low‘, ‘image‘, 0, 255, s_low)
cv2.createTrackbar(‘S high‘, ‘image‘, 0, 255, s_high)
cv2.createTrackbar(‘V low‘, ‘image‘, 0, 255, v_low)
cv2.createTrackbar(‘V high‘, ‘image‘, 0, 255, v_high)

while True:
    dst = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # BGR轉HSV
    dst = cv2.inRange(dst, hsv_low, hsv_high) # 通過HSV的高低閾值,提取圖像部分區域
    cv2.imshow(‘dst‘, dst)
    if cv2.waitKey(1) & 0xFF == ord(‘q‘):
        break
cv2.destroyAllWindows()

程序運行的效果如下,我們拉動滑塊會自動改變HSV的高低閾值,進而根據高低閾值提取的圖像區域也會改變:

技術分享圖片

RGB色彩空間和HSV色彩空間的理解