1. 程式人生 > >opencv:HSV顏色模型

opencv:HSV顏色模型

之前操作影象資料通常使用的是RGB顏色模型。RGB是通過三個顏色通道(R、G、B)的疊加得到不同的顏色的。今天學習了一個新的顏色模型:HSV。
作為對比,先看熟悉的RGB。RGB中有三個引數,分別代表紅綠藍三基色的亮度,範圍是0~255。這裡的三基色是指光的三基色,三基色組合可以得到大部分顏色。
HSV中也有三個引數,H、S、V,分別代表色調(Hue),飽和度(Saturation),明度(Value)。其中色調的範圍是0~360°,以角度形式給出顏色光譜構成的度量。飽和度是0~100°,給出主波長中純光的比例,表示一種顏色距離相同亮度相同時,灰度的程度。明度、又叫純度,給出相對於白色光照強度的亮度,範圍在0~100°.

在OpenCV中,色彩引數範圍由於表達方式的限制有所調整:H範圍0~180,S範圍0~255,V範圍0~255。

要在HSV色彩空間下處理影象,首先要轉換色彩模型:

Mat img = imread(fname);
imshow("src", img);
vector<Mat> channels;
cvtColor(img, img, COLOR_BGR2HSV);
split(img, channels);

注意,在Opencv中,imshow函式顯示的影象是預設RGB色彩模型的,如果轉換色彩模型後再用imshow會導致影象顯示發生偏差。
在分離出HSV通道後,就可以對各個通道操作達到想要的效果。

一個例子:
查表得知紅色的h值範圍在156~180(通常對於想要的色彩範圍可以提前採集得知),對一張圖將其中的紅色全部換成綠色(即將其角度增加60)。程式碼如下:

void hsv_test(string fname){
    Mat img = imread(fname);
    resize(img, img, Size(), 0.2, 0.2);
    imshow("src", img);
    vector<Mat> channels;
    for (int i = 0; i < img.rows; i++){//每一行
        unsigned char
* data = channels[0].ptr<unsigned char>(i); for (int j = 0; j < img.cols; j++){//每一個 int temp = data[j]; //temp *= 2*exp(1-temp) + 1; if(temp<180 && temp>156)temp = (temp + 60) % 180; //if (temp >= 255)temp = 255; data[j] = temp; } } Mat result; merge(channels, result); cvtColor(result, result, COLOR_HSV2BGR); imshow("result", result); waitKey(); system("pause"); }

執行結果:
這裡寫圖片描述
這裡寫圖片描述