opencv 彩色圖像分割(inrange)


  灰度圖像大多通過算子尋找邊緣和區域生長融合來分割圖像。

  彩色圖像增加了色彩信息,可以通過不同的色彩值來分割圖像,常用彩色空間HSV/HSI, RGB, LAB等都可以用於分割!

  筆者主要介紹inrange() 來划分顏色區域。先看看OpenCV的文檔:

  C++: void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)

  C: void cvInRangeS(const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst) 

  • src – first input array.
  • lowerb – inclusive lower boundary array or a scalar.
  • upperb – inclusive upper boundary array or a scalar.
  • dst – output array of the same size as src and CV_8U type
  • For two-channel arrays:

    \texttt{dst} (I)= \texttt{lowerb} (I)_0  \leq \texttt{src} (I)_0 \leq  \texttt{upperb} (I)_0  \land \texttt{lowerb} (I)_1  \leq \texttt{src} (I)_1 \leq  \texttt{upperb} (I)_1

  • and so forth.

  意思主要是:

  src:輸入圖像,CV2常用Mat類型;

  lowerb:lower boundary下限,scalar類型的像素值,單通道scalar取一個值就行,彩圖3通道scalar三個值;

  upperb:上限,類型與lowerb同理;

  dst:輸出圖像,尺寸與src一致,類型是CV_8U,但沒有指定通道數。

  對於多通道的輸入,輸出結果是各個通道的結果相與,當各通道結果都在上下限之內時,輸出為255,否則為0。因此也有人將輸出理解為掩碼模板!

 

  看個例子吧:  

 1 int hmax = 360;
 2 int hmax_Max = 360;
 3 //飽和度  
 4 int smin = 0;
 5 int smin_Max = 255;
 6 int smax = 255;
 7 int smax_Max = 255;
 8 //亮度  
 9 int vmin = 106;
10 int vmin_Max = 255;
11 int vmax = 250;
12 int vmax_Max = 255;
13 //顯示原圖的窗口  
14 string windowName = "src";
15 //輸出圖像的顯示窗口  
16 string dstName = "dst";
17 //輸出圖像  
18 Mat dst;
19 //回調函數  
20 void callBack(int, void*)
21 {
22     //輸出圖像分配內存  
23     dst = Mat::zeros(img.size(), CV_32FC3);
24     //掩碼  
25     Mat mask;
26     inRange(hsv, Scalar(hmin, smin / float(smin_Max), vmin / float(vmin_Max)), Scalar(hmax, smax / float(smax_Max), vmax / float(vmax_Max)), mask);
27     //只保留  
28     for (int r = 0; r < bgr.rows; r++)
29     {
30         for (int c = 0; c < bgr.cols; c++)
31         {
32             if (mask.at<uchar>(r, c) == 255)
33             {
34                 dst.at<Vec3f>(r, c) = bgr.at<Vec3f>(r, c);
35             }
36         }
37     }
38     //輸出圖像  
39     imshow(dstName, dst);
40     //保存圖像  
41     dst.convertTo(dst, CV_8UC3, 255.0, 0);
42     imwrite("HSV_inRange.jpg", dst);
43 }
44 void test_main()
45 {
46     //輸入圖像  
47     img = imread("E:\\素材圖片\\1.png",1);
48     if (!img.data || img.channels() != 3)
49         return ;
50     imshow(windowName, img);
51     //彩色圖像的灰度值歸一化  
52     img.convertTo(bgr, CV_32FC3, 1.0 / 255, 0);
53     //顏色空間轉換  
54     cvtColor(bgr, hsv, COLOR_BGR2HSV);
55     //定義輸出圖像的顯示窗口  
56     namedWindow(dstName, WINDOW_NORMAL);
57     //調節色相 H  
58     createTrackbar("hmin", dstName, &hmin, hmin_Max, callBack);
59     createTrackbar("hmax", dstName, &hmax, hmax_Max, callBack);
60     //調節飽和度 S  
61     createTrackbar("smin", dstName, &smin, smin_Max, callBack);
62     createTrackbar("smax", dstName, &smax, smax_Max, callBack);
63     //調節亮度 V  
64     createTrackbar("vmin", dstName, &vmin, vmin_Max, callBack);
65     createTrackbar("vmax", dstName, &vmax, vmax_Max, callBack);
66     callBack(0, 0);
67     waitKey(0);
68     return;
69 }

  函數外的為全局變量,頭文件自己加上就行。

  放兩張不同的圖片分割結果:

    

  第一種是通過調節H值將紅色和綠色分割開,SV的值我選擇保持默認。(忽略結果圖右下角的輸入法。。。)

      

  第二種調節H值並沒有什么改善,但是可以調節S飽和度,將車牌前景和背景對比的更加強烈。(忽略結果圖右下角的輸入法。。。)

  更多調節策略歡迎大家評價~~

附上完整可運行代碼路徑,還是不能運行的注意 readme。 https://github.com/chenzhefan/inrange_color


免責聲明!

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



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