一、知識點:
1、色彩空間轉換函數
? (1)、void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0, AlgorithmHint hint = cv::ALGO_HINT_DEFAULT );
? (2)、將圖像從一種顏色空間轉換為另一種。
? (3)、參數說明:
? ? ? src: 輸入圖像,即要進行顏色空間變換的原圖像。
?? ? ?dst: 輸出圖像,即進行顏色空間變換后的圖像。
?? ? ?code: ColorConversionCodes枚舉值,確定從什么顏色空間轉換到什么顏色空間,如: COLOR_BGR2RGB、 COLOR_BGRA2RGBA、 COLOR_BGR2GRAY、 COLOR_BGR2HSV。
?? ? ?dstCn: 指定目標圖像的通道數,若為0,則通道數由src和code決定。
?? ? ?hint: 算法提示。
? (5)、注意:
? ? ? 對于RGB色彩空間,OpenCV的通道順序是BGR,即標準24位彩色圖像,第一個字節是藍色分量,第二個字節是綠色分量,第三個字節是紅色分量,第四、第五、第六依次是第二個像素的藍、綠、紅分量,以此類推。
?? ? ?cvtColor用COLOR_BGR2RGB和用COLOR_RGB2BGR來轉換原RGB色彩空間的圖像,效果是一樣的。
?? ? ?本質上內部調用mixChannels()函數,都是將原先的B通道拷貝給目標的R通道,將原先的G通道拷貝給目標的G通道,將原先的R通道拷貝給目標的B通道。
?? ? ?
2、HSV顏色空間
? (1)、H: 色相,即什么顏色,opencv中取值范圍[0, 180]。
? (2)、S: 飽和度,即顏色有多深,opencv中取值范圍[0, 255]。
? (3)、V: 色調、純度、亮度,即顏色有多亮,opencv中取值范圍[0, 255]。
? (4)、HSV顏色范圍:
? ? ? 黑: H[0, 180],S[0, 255],V[0, 46]。
?? ? ?灰: H[0, 180],S[0, 43],V[46, 220]。
?? ? ?白: H[0, 180],S[0, 30],V[221, 255]。
?? ? ?紅: H[0, 10]、[156、 180], S[43, 255],V[46, 255]。?
?? ? ?橙: H[11, 25],S[43, 255],V[46, 255]。
?? ? ?黃: H[26, 34],S[43, 255],V[46, 255]。
?? ? ?綠: H[35, 77],S[43, 255],V[46, 255]。
?? ? ?青: H[78, 99],S[43, 255],V[46, 255]。
?? ? ?藍: H[100, 124],S[43, 255],V[46, 255]。
?? ? ?紫: H[125, 155],S[43, 255],V[46, 255]。?
? (5)、HSV比RGB更容易區分出顏色。
??
3、void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);
? (1)、創建一個掩碼dst,將原始圖像src中滿足給定范圍[lowerb, upperb]條件的像素置255,其余置0。
? (2)、參數說明:
? ? ? src: 輸入圖像。
?? ? ?lowerb: 下界,與輸入圖像類型和通道數相同的標量。
?? ? ?upperb: 上界,與輸入圖像類型和通道數相同的標量。
?? ? ?dst: 輸出掩碼,類型為CV_8UC1。
?? ? ?
?? ? ?
二、示例代碼: 從原始綠色背景圖像中摳出人物到紅色背景圖像中
#include <iostream>
#include <opencv2/opencv.hpp>int main()
{cv::Mat src1 = cv::Mat::zeros(3, 3, CV_8UC3);src1 = cv::Scalar(100, 20, 200);std::cout << "src1:" << std::endl << src1 << std::endl;//先把原B通道給目標R通道,再把原G通道給目標G通道,再把原R通道給目標B通道。cv::Mat dst2;cv::cvtColor(src1, dst2, cv::COLOR_BGR2RGB);std::cout << "dst2:" << std::endl << dst2 << std::endl;//先把原R通道給目標B通道,再把原G通道給目標G通道,再把原B通道給目標R通道。//所以dst2和dst3的結果是一樣的。cv::Mat dst3;cv::cvtColor(src1, dst3, cv::COLOR_RGB2BGR);std::cout << "dst3:" << std::endl << dst3 << std::endl;cv::Mat src2 = cv::imread("../images/9.png");if (src2.empty()){std::cout << "load src2 image error..." << std::endl;return -1;}else{std::cout << "load src2 image ok..." << std::endl;cv::imshow("原始圖像", src2);}//轉換成HSV色彩空間后,顯示的HSV圖像顏色變了,猜測是imshow把hsvImage還是按BGR的方式顯示。cv::Mat hsvImage;cv::cvtColor(src2, hsvImage, cv::COLOR_RGB2HSV);cv::imshow("HSV圖像", hsvImage);//綠色的HSV最小值cv::Scalar(35, 43, 46),最大值cv::Scalar(77, 255, 255)。//把圖像的綠色背景在mask中對應位置置255,其余置0。cv::Mat mask;cv::inRange(hsvImage, cv::Scalar(35, 43, 46), cv::Scalar(77, 255, 255), mask);cv::imshow("mask", mask);//mask取反,綠色背景在mask中對應位置置0,其余置255。cv::bitwise_not(mask, mask);cv::imshow("mask not", mask);//創建一個紅色背景圖cv::Mat redbackImage = cv::Mat::zeros(src2.size(), src2.type());redbackImage = cv::Scalar(40, 40, 200);//摳圖拷貝到紅色背景圖上src2.copyTo(redbackImage, mask);cv::imshow("ROI區域提取", redbackImage);cv::waitKey(0);return 0;
}
輸出結果:
src1:
[100, ?20, 200, 100, ?20, 200, 100, ?20, 200;
?100, ?20, 200, 100, ?20, 200, 100, ?20, 200;
?100, ?20, 200, 100, ?20, 200, 100, ?20, 200]
dst2:
[200, ?20, 100, 200, ?20, 100, 200, ?20, 100;
?200, ?20, 100, 200, ?20, 100, 200, ?20, 100;
?200, ?20, 100, 200, ?20, 100, 200, ?20, 100]
dst3:
[200, ?20, 100, 200, ?20, 100, 200, ?20, 100;
?200, ?20, 100, 200, ?20, 100, 200, ?20, 100;
?200, ?20, 100, 200, ?20, 100, 200, ?20, 100]
load src2 image ok...
?