[OpenCV] Samples 16: Decompose and Analyse RGB channels

物体的颜色特征决定了灰度处理不是万能,对RGB分别处理具有相当的意义。

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include "cv.h"
  4 #include <highgui.h>
  5 #include <opencv2/opencv.hpp>
  6 #include <opencv2/legacy/legacy.hpp>
  7 #include <opencv2/nonfree/nonfree.hpp>
  8 #include <opencv2/nonfree/features2d.hpp>
  9 #include <opencv2/flann/flann.hpp>
 10 
 11 
 12 using namespace std;
 13 using namespace cv;
 14 
 15 
 16 #define PATH_IMG01 "../lolo.jpg"
 17 
 18 
 19 IplImage *g_pGrayImage = NULL;
 20 IplImage *g_pGrayImg4ChannelR = NULL;
 21 IplImage *g_pGrayImg4ChannelG = NULL;
 22 IplImage *g_pGrayImg4ChannelB = NULL;
 23 
 24 IplImage *g_pBinaryImg4ChannelR = NULL;
 25 IplImage *g_pBinaryImg4ChannelG = NULL;
 26 IplImage *g_pBinaryImg4ChannelB = NULL;
 27 IplImage *g_pBinaryImg4ChannelC = NULL;
 28 
 29 const char *pstrWindowsToolBarName4ChB = "ToolBarName4ChannelB";
 30 const char *pstrWindowsToolBarName4ChG = "ToolBarName4ChannelG";
 31 const char *pstrWindowsToolBarName4ChR = "ToolBarName4ChannelR";
 32 const char *pstrWindowsToolBarName4ChC = "ToolBarName4ChannelC";
 33 
 34 const char *pstrWindowsSrcTitle = "SrcImageTitle";
 35 const char *pstrWindowsBinaryTitle4ChB = "BinaryTitle4B";
 36 const char *pstrWindowsBinaryTitle4ChG = "BinaryTitle4G";
 37 const char *pstrWindowsBinaryTitle4ChR = "BinaryTitle4R";
 38 const char *pstrWindowsBinaryTitle4ChC = "BinaryTitle4C";
 39 
 40 const char *pstr_title_chB = "Binary Image for Channel B";
 41 const char *pstr_title_chG = "Binary Image for Channel G";
 42 const char *pstr_title_chR = "Binary Image for Channel R";
 43 
 44 
 45 void on_trackbar_channelB(int pos)
 46 {
 47     Mat src = Mat(g_pGrayImg4ChannelB);
 48     Mat dst;
 49     IplImage img_out;
 50 
 51     ////////////////////////////////////////////////////////
 52     GaussianBlur(src,dst,Size(5,5),0,0);
 53 //    medianBlur(src,dst,10);
 54 //    blur(src,dst,Size(5,5),Point(-1,-1));
 55 //    bilateralFilter(src,dst,25, 25*2, 25/2);
 56     img_out = IplImage(dst);
 57     ////////////////////////////////////////////////////////
 58 
 59     // (1)
 60     cvThreshold(&img_out, g_pBinaryImg4ChannelB, pos, 255, CV_THRESH_BINARY);
 61 
 62     // (2)
 63     int gap = 50;
 64     IplImage *pBinaryImg4ChannelB = cvCreateImage(cvGetSize(g_pGrayImg4ChannelB), IPL_DEPTH_8U, 1);
 65     cvThreshold(&img_out, pBinaryImg4ChannelB, pos + gap, 255, CV_THRESH_BINARY);
 66 
 67     // (3)
 68     IplImage *pBinaryImg4ChannelB_DV = cvCreateImage(cvGetSize(g_pBinaryImg4ChannelB), IPL_DEPTH_8U, 1);
 69     cvAbsDiff(g_pBinaryImg4ChannelB, pBinaryImg4ChannelB, pBinaryImg4ChannelB_DV);
 70 //    cvShowImage(pstrWindowsBinaryTitle4ChB, pBinaryImg4ChannelB_DV);
 71     cvShowImage(pstrWindowsBinaryTitle4ChB, g_pBinaryImg4ChannelB);
 72 }
 73 
 74 
 75 void on_trackbar_channelG(int pos)
 76 {
 77     Mat src = Mat(g_pGrayImg4ChannelG);
 78     Mat dst;
 79     IplImage img_out;
 80 
 81     ////////////////////////////////////////////////////////
 82     GaussianBlur(src,dst,Size(5,5),0,0);
 83     img_out = IplImage(dst);
 84     ////////////////////////////////////////////////////////
 85 
 86     // (1)
 87     cvThreshold(&img_out, g_pBinaryImg4ChannelG, pos, 255, CV_THRESH_BINARY);
 88 
 89     // (2)
 90     int gap = 50;
 91     IplImage *pBinaryImg4ChannelG = cvCreateImage(cvGetSize(g_pGrayImg4ChannelG), IPL_DEPTH_8U, 1);
 92     cvThreshold(&img_out, pBinaryImg4ChannelG, pos + gap, 255, CV_THRESH_BINARY);
 93 
 94     // (3)
 95     IplImage *pBinaryImg4ChannelG_DV = cvCreateImage(cvGetSize(g_pBinaryImg4ChannelG), IPL_DEPTH_8U, 1);
 96     cvAbsDiff(g_pBinaryImg4ChannelG, pBinaryImg4ChannelG, pBinaryImg4ChannelG_DV);
 97 //    cvShowImage(pstrWindowsBinaryTitle4ChG, pBinaryImg4ChannelG_DV);
 98     cvShowImage(pstrWindowsBinaryTitle4ChG, g_pBinaryImg4ChannelG);
 99 }
100 
101 
102 void on_trackbar_channelR(int pos)
103 {
104     Mat src = Mat(g_pGrayImg4ChannelR);
105     Mat dst;
106     IplImage img_out;
107 
108     ////////////////////////////////////////////////////////
109     GaussianBlur(src,dst,Size(5,5),0,0);
110     img_out = IplImage(dst);
111 //    cvShowImage( "Task 8*: Gaussian Blur", &img_out);
112 //    cvWaitKey(0);
113     ////////////////////////////////////////////////////////
114 
115     // (1)
116     cvThreshold(&img_out, g_pBinaryImg4ChannelR, pos, 255, CV_THRESH_BINARY);
117 
118     // (2)
119     int gap = 50;
120     IplImage *pBinaryImg4ChannelR = cvCreateImage(cvGetSize(g_pGrayImg4ChannelR), IPL_DEPTH_8U, 1);
121     cvThreshold(&img_out, pBinaryImg4ChannelR, pos + gap, 255, CV_THRESH_BINARY);
122 
123     // (3)
124     IplImage *pBinaryImg4ChannelR_DV = cvCreateImage(cvGetSize(g_pBinaryImg4ChannelR), IPL_DEPTH_8U, 1);
125     cvAbsDiff(g_pBinaryImg4ChannelR, pBinaryImg4ChannelR, pBinaryImg4ChannelR_DV);
126 //    cvShowImage(pstrWindowsBinaryTitle4ChR, pBinaryImg4ChannelR_DV);
127     cvShowImage(pstrWindowsBinaryTitle4ChR, g_pBinaryImg4ChannelR);
128 }
129 
130 
131 void on_trackbar_channelC(int pos)
132 {
133     cvOr(g_pBinaryImg4ChannelB, g_pBinaryImg4ChannelG, g_pBinaryImg4ChannelC);
134     cvOr(g_pBinaryImg4ChannelC, g_pBinaryImg4ChannelR, g_pBinaryImg4ChannelC);
135 
136     cvShowImage(pstrWindowsBinaryTitle4ChC, g_pBinaryImg4ChannelC);
137 }
138 
139 
140 
141 
142 
143 int main(void)
144 {
145     // 1. src image and resize.
146     Mat src = imread(PATH_IMG01);
147     const int zoom = 2;
148     resize(src, src, Size(src.cols/zoom, src.rows/zoom));
149 
150     IplImage srcImage = IplImage(src);
151     IplImage *pSrcImage = &srcImage;
152 
153 
154     // 2. split r, g, b channel images.
155     Mat channel[3];
156 
157     split(pSrcImage, channel);
158 
159 //    imshow("B",channel[0]);
160 //    imshow("G",channel[1]);
161 //    imshow("R",channel[2]);
162 //    waitKey(0);
163 
164     IplImage img_channelB = IplImage(channel[0]);
165     IplImage img_channelG = IplImage(channel[1]);
166     IplImage img_channelR = IplImage(channel[2]);
167 
168     g_pGrayImg4ChannelB = &img_channelB;
169     g_pGrayImg4ChannelG = &img_channelG;
170     g_pGrayImg4ChannelR = &img_channelR;
171 
172     // 3. get r, g, b binary images.
173     g_pBinaryImg4ChannelB = cvCreateImage(cvGetSize(g_pGrayImg4ChannelB), IPL_DEPTH_8U, 1);
174     g_pBinaryImg4ChannelG = cvCreateImage(cvGetSize(g_pGrayImg4ChannelG), IPL_DEPTH_8U, 1);
175     g_pBinaryImg4ChannelR = cvCreateImage(cvGetSize(g_pGrayImg4ChannelR), IPL_DEPTH_8U, 1);
176 
177 
178     // 4.1 show src image.
179     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
180     cvShowImage(pstrWindowsSrcTitle, pSrcImage);
181 
182     // 4.2 create r, g, b windows.
183     cvNamedWindow(pstrWindowsBinaryTitle4ChB, CV_WINDOW_AUTOSIZE);
184     cvNamedWindow(pstrWindowsBinaryTitle4ChG, CV_WINDOW_AUTOSIZE);
185     cvNamedWindow(pstrWindowsBinaryTitle4ChR, CV_WINDOW_AUTOSIZE);
186 
187     // 4.3 create toolbar for r, g, b windows.
188     int nThreshold = 61;
189     cvCreateTrackbar(pstrWindowsToolBarName4ChB, pstrWindowsBinaryTitle4ChB, &nThreshold, 254, on_trackbar_channelB);
190     cvCreateTrackbar(pstrWindowsToolBarName4ChG, pstrWindowsBinaryTitle4ChG, &nThreshold, 254, on_trackbar_channelG);
191     cvCreateTrackbar(pstrWindowsToolBarName4ChR, pstrWindowsBinaryTitle4ChR, &nThreshold, 254, on_trackbar_channelR);
192 
193     // 4.4 create combine result show.
194     g_pBinaryImg4ChannelC = cvCreateImage(cvGetSize(g_pGrayImg4ChannelR), IPL_DEPTH_8U, 1);
195     cvNamedWindow(pstrWindowsBinaryTitle4ChC, CV_WINDOW_AUTOSIZE);
196     cvCreateTrackbar(pstrWindowsToolBarName4ChC, pstrWindowsBinaryTitle4ChC, &nThreshold, 254, on_trackbar_channelC);
197 
198     // 4.5 run.
199     on_trackbar_channelB(1);
200     on_trackbar_channelG(1);
201     on_trackbar_channelR(1);
202     on_trackbar_channelC(1);
203 
204     cvWaitKey(0);
205 
206     // 5. destroy trash.
207     cvDestroyWindow(pstrWindowsSrcTitle);
208     cvDestroyWindow(pstrWindowsBinaryTitle4ChB);
209     cvDestroyWindow(pstrWindowsBinaryTitle4ChG);
210     cvDestroyWindow(pstrWindowsBinaryTitle4ChR);
211     cvDestroyWindow(pstrWindowsBinaryTitle4ChC);
212 
213     cvReleaseImage(&pSrcImage);
214     cvReleaseImage(&g_pBinaryImg4ChannelB);
215     cvReleaseImage(&g_pBinaryImg4ChannelG);
216     cvReleaseImage(&g_pBinaryImg4ChannelR);
217     cvReleaseImage(&g_pBinaryImg4ChannelC);
218 
219     return 0;
220 }
View Code

 

HSV channels 能更好地解决问题? 亮度60-80之间是一个不错的判定效果。

 

IplImage* pSrcHsv=cvCreateImage(cvGetSize(pSrcImage),IPL_DEPTH_8U,3);
cvCvtColor(pSrcImage, pSrcHsv, CV_BGR2HSV);

Mat channel[3];
split(pSrcHsv, channel);
相关代码

 

通过亮度通道进行二值刷选后,再采用轮廓线判断继续缩小范围。

 

是否有判别基本几何形状的高效方法,找出其中的凸四边形?

Sol 01: “面积比”: size of contour/size of its bounding rectangle

 

 

[OpenCV] Samples 04: contours2

[OpenCV] Samples 05: convexhull

 

posted @ 2017-03-20 12:22  郝壹贰叁  阅读(416)  评论(0编辑  收藏  举报