[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 }
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