opencv之顏色過濾只留下圖片中的紅色區域


如圖,這次需要在圖片中找到卷尺的紅色刻度,所以需要對圖像做過濾,只留下紅色部分。

一開始的想法是分別找到RGB值,然后找到紅色區域的部分保留就可以了,不過好像很難確定紅色區域的RGB取值范圍,所以要把圖片轉化到HSV空間中去。

在opencv中直接使用cvCvtColor函數就可以啦。

 

[cpp]  view plain  copy
 
  1. IplImage* hsv = cvCreateImage( cvGetSize(image), 8, 3 );    
  2.       
  3. cvCvtColor(image,hsv,CV_BGR2HSV);  

 

 

opencv 的H范圍是0~180,紅色的H范圍大概是(0~8)∪(160,180) ,S是飽和度,一般是大於一個值,S過低就是灰色(參考值S>80),V是亮度,過低就是黑色,過高就是白色(參考值220>V>50)。

所以接下來要做的就是遍歷圖像,獲取圖像每個像素點的H,S,V分量,然后做判斷,滿足條件的就保留,不滿足的就賦值為黑色。

我是用opencv中的IplImage來存儲圖片的。

IplImage獲取像素點的方式如下:

 

[cpp]  view plain  copy
 
  1. CvScalar s_hsv = cvGet2D(hsv, j, i);//獲取像素點為(i, j)點的HSV的值,i是width值,j是height值  

IplImage對像素點賦值的方式如下:

 

 

[cpp]  view plain  copy
 
  1. CvScalar s;  
  2. cvSet2D(hsv, j ,i, s);//對(i,j)處的像素點賦值  

分別取得H,S,V分量,注意圖像轉化的時候BGR2HSV,所以s.val[0]是B或H的值,s.val[1]是G或S的值,s.val[2]則是R或V的值。

 

因為師弟喜歡用CvMat,所以輸入都改成了CvMat,使用的時候inputImage是希望過濾的圖片,outputImage則為輸出圖片,因為outputImage會在函數中進行空間申請與賦值,所以傳入參數的時候直接把它設成NULL就可以了。

另外要注意一點,因為是對彩色圖像做實驗,所以如果傳入的圖片不是3通道的彩色圖片,那么就會出內存錯誤。

以下打開圖片或創建圖片的方式都是單通道方式,會出現內存錯誤。

IplImage *input = cvLoadImage(path, 0),
CvMat* M = cvCreateMat(4,4,CV_32FC1); //或是8UC1, 因為C1表示nChannel = 1,也就是單通道

 

 

 

[cpp]  view plain  copy
 
  1. void colorFilter(CvMat *inputImage, CvMat *&outputImage)  
  2. {  
  3.     int i, j;  
  4.     IplImage* image = cvCreateImage(cvGetSize(inputImage), 8, 3);  
  5.     cvGetImage(inputImage, image);      
  6.     IplImage* hsv = cvCreateImage( cvGetSize(image), 8, 3 );    
  7.       
  8.     cvCvtColor(image,hsv,CV_BGR2HSV);  
  9.     int width = hsv->width;  
  10.     int height = hsv->height;  
  11.     for (i = 0; i < height; i++)  
  12.         for (j = 0; j < width; j++)  
  13.         {  
  14.             CvScalar s_hsv = cvGet2D(hsv, i, j);//獲取像素點為(j, i)點的HSV的值   
  15.             /* 
  16.                 opencv 的H范圍是0~180,紅色的H范圍大概是(0~8)∪(160,180)  
  17.                 S是飽和度,一般是大於一個值,S過低就是灰色(參考值S>80), 
  18.                 V是亮度,過低就是黑色,過高就是白色(參考值220>V>50)。 
  19.             */  
  20.             CvScalar s;  
  21.             if (!(((s_hsv.val[0]>0)&&(s_hsv.val[0]<8)) || (s_hsv.val[0]>120)&&(s_hsv.val[0]<180)))  
  22.             {  
  23.                 s.val[0] =0;  
  24.                 s.val[1]=0;  
  25.                 s.val[2]=0;  
  26.                 cvSet2D(hsv, i ,j, s);  
  27.             }  
  28.               
  29.               
  30.         }  
  31.     outputImage = cvCreateMat( hsv->height, hsv->width, CV_8UC3 );  
  32.     cvConvert(hsv, outputImage);  
  33.     cvNamedWindow("filter");  
  34.     cvShowImage("filter", hsv);  
  35.     waitKey(0);  
  36.     cvReleaseImage(&hsv);  
  37. }  

 

關於函數還有一點要說明,H分量我取得是(0,8),(120,180),S與V分量沒有做篩選,如果按照注釋部分的進行篩選結果不是很好。

結果如圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM