首頁 > 軟體

基於opencv實現視訊中的顏色識別功能

2022-07-22 22:02:25

顏色識別的原理

opencv中的顏色模型

RGB

RGB具有三個通道其,分別表示紅色通道®,綠色通道(G),藍色通道(B),3個通道在opencv中的取值均為0~255,它的顏色由3個通道的取值來共同決定,因此如果使用RGB影象來進行顏色的識別,會丟失很多的顏色。

HSV

HSV具有三個通道,其分別表示色調(H),飽和度(S),亮度(V),3個通道在opencv中的取值分別如下:

  • H:0~180
  • S:0~255
  • V:0~255

其中H通道和S通道決定了顏色,V通道決定亮度
各種顏色對應的三個通道的取值表如下:

因此通過限制HSV通道中相對應的數值,就可以識別出對應的顏色

顏色識別的實現(c++)

1.讀取攝像頭的實時畫面

VideoCapture capture(1);//0為電腦本身攝像頭,1位外接攝像頭

2.讀取攝像頭的當前一幀的資料並轉換到HSV空間

capture >> frame; //讀取當前幀
cvtColor(frame, imgHSV, COLOR_BGR2HSV);

3.對HSV影象進行直方圖均衡化
在此處使用直方圖均衡化是因為可以使用這種方法可以使原來比較少畫素的灰度會被分配到別的灰度去,畫素相對集中, 處理後灰度範圍變大,對比度變大,清晰度變大,所以能有效增強影象。

split(imgHSV,temporary);
equalizeHist(temporary[2], temporary[2]);
merge(temporary, imgHSV);   //將HSV影象分割通道,並且做直方圖的均衡化

使用equalizeHist()函數,其輸入必須是單通道的,因此使用split函數將得到的HSV影象分割為三個通道之後,在進行直方圖均衡化,然後再使用merge函數來合併三個通道。
此處僅對V通道進行了直方圖均衡化,因為通過比對發現只對V通道進行效果最好,具體的原因還不清楚。

4.將直方圖均衡化之後,使用inRange()函數來進行影象的識別

inRange(imgHSV, Scalar(H_W_L, S_W_L, V_W_L), Scalar(H_W_H, S_W_H, V_W_H), image);

其中H_W_L,H_W_L, S_W_L, V_W_L. . . 等數值分別為前面表格對應的顏色值的最小值和最大值。
此函數是將在範圍內的畫素值為255,其與為0,反映到影象上就是,選中的顏色為白色,其與的均為黑色。
操作到此顏色可以進行識別,但是效果可能不會很好,因此可以再使用開操作來消除噪點,去掉小的干擾快,再使用閉操作來填充閉合區域。

5.開操作

kernel = getStructuringElement(MORPH_RECT, Size(3, 3));//3*3的矩形折積核,只要是奇數的都可以
morphologyEx(image,image,2,kernel);

6.閉操作

morphologyEx(image,image,3,kernel);

原始碼

#include <opencv2opencv.hpp>  
using namespace cv;
using namespace std;
int main()
{
	Mat frame,imgHSV,image,kernel;
	vector<Mat>temporary;
	int H_W_L = 0, H_W_H = 180;
	int S_W_L = 0, S_W_H = 30;
	int V_W_L = 221, V_W_H = 255;
	VideoCapture capture(1);//讀取視攝像頭實時畫面資料,0預設是筆電的攝像頭;如果是外接攝像頭,這裡改為1
	while (true)
	{
		capture >> frame; //讀取當前幀
		
		if (!frame.empty())
		{          //判斷輸入的視訊幀是否為空的
			cvtColor(frame, imgHSV, COLOR_BGR2HSV);
			//threshold(gray, two_value, 125, 255, THRESH_BINARY);//二值影象
			
			split(imgHSV,temporary);
			equalizeHist(temporary[2], temporary[2]);
			/*equalizeHist(temporary[1], temporary[1]);
			equalizeHist(temporary[0], temporary[0]);*/
			merge(temporary, imgHSV);   //將HSV影象分割通道,並且做直方圖的均衡化
			inRange(imgHSV, Scalar(H_W_L, S_W_L, V_W_L), Scalar(H_W_H, S_W_H, V_W_H), image);
			kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
			morphologyEx(image,image,2,kernel);
			morphologyEx(image,image,3,kernel);
			imshow("直方圖", imgHSV);
			imshow("原圖",frame);
			imshow("window", image);  //在window視窗顯示frame攝像頭資料畫面
		}
		if (waitKey(20) == 'q')   //延時20ms,獲取使用者是否按鍵的情況,如果按下q,會推出程式 
			break;
	}
	capture.release();     //釋放攝像頭資源
	destroyAllWindows();   //釋放全部視窗
	return 0;
}

##結果

到此這篇關於基於opencv實現視訊中的顏色識別的文章就介紹到這了,更多相關OpenCV顏色識別內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com