1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title>手势识别代码分析</title> 5 <script type="text/javascript"> 6 var arr = new Array("resizewindow", "init_hand_YCrCb", "init_hand_HSV", "init_laplace", "inti_threshold", 7 "hand_HSV", "init_hand_template", ‘reduce_noise‘, "hand_template_match", "hand_direction", ‘hand_contours‘ 8 ,"hand_draw"); 9 var selfarr = new Array("resize","ihy","ihh","ill","ith","hh",‘iht‘,‘rn‘,‘htm‘,‘hd‘,‘hc‘,‘hdr‘,‘hdr2‘); 10 //{ ‘1‘: "resizewindow", ‘2‘: "b", ‘3‘: }; 11 function here(variable,selfid) { 12 13 for (var i = 0; i < arr.length; i++) 14 { 15 var tem = arr[i]; 16 document.getElementById(tem).style.display = "none"; 17 } 18 for (var i = 0; i < selfarr.length; i++) 19 { 20 var tem = selfarr[i]; 21 document.getElementById(tem).style.color = "black"; 22 } 23 document.getElementById(selfid).style.color = "red"; 24 var now = document.getElementById(variable); 25 now.style.display = ""; 26 } 27 28 </script> 29 </head> 30 <body style="background-color:lightblue"> 31 <div> 32 <table align="left" > 33 <tr><td> int main()</td></tr> 34 <tr><td> {</td></tr> 35 <tr><td> int c = 0;</td></tr> 36 <tr><td> double scale = 0.5;</td></tr> 37 <tr><td> //打开摄像头</td></tr> 38 <tr><td> CvCapture* capture = cvCaptureFromCAM(0);</td></tr> 39 <tr><td> src = cvQueryFrame(capture);</td></tr> 40 <tr><td> //获得图像大小</td></tr> 41 <tr><td> sz = cvGetSize(src);</td></tr> 42 <tr><td> newSize.height = (int)(sz.height * scale);</td></tr> 43 <tr><td> newSize.width = (int)(sz.width * scale);</td></tr> 44 <tr><td> sz = newSize;</td></tr> 45 <tr><td> //建立所有窗体</td></tr> 46 <tr><td onclick="here(‘resizewindow‘,‘resize‘)"id="resize"> resizeAllWindow();</td></tr> 47 <tr><td> tmp1 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 48 <tr><td> tmp2 = cvCreateImage(sz,IPL_DEPTH_8U,3);</td></tr> 49 <tr><td> tmp3 = cvCreateImage(sz,IPL_DEPTH_8U,3);</td></tr> 50 <tr><td> src2 = cvCreateImage(sz,IPL_DEPTH_8U,3);</td></tr> 51 <tr><td> smooth1 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 52 <tr><td> smooth2 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 53 <tr><td> smooth3 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 54 <tr><td> smooth4 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 55 <tr><td> smooth5 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 56 <tr><td onclick="here(‘init_hand_YCrCb‘,‘ihy‘)"id="ihy"> init_hand_YCrCb();</td></tr> 57 <tr><td onclick="here(‘init_hand_HSV‘,‘ihh‘)"id="ihh"> init_hand_HSV();</td></tr> 58 <tr><td onclick="here(‘init_laplace‘,‘ill‘)"id="ill"> init_laplace();</td></tr> 59 <tr><td onclick="here(‘inti_threshold‘,‘ith‘)"id="ith"> inti_threshold();</td></tr> 60 <tr><td> //载入匹配的模板</td></tr> 61 <tr><td id="iht"onclick="here(‘init_hand_template‘,‘iht‘)"> init_hand_template();</td></tr> 62 <tr><td> src1 = cvCreateImage(sz,IPL_DEPTH_8U,3);</td></tr> 63 <tr><td> /////////////////////开始循环///////////////////////////////</td></tr> 64 <tr><td> while( c != 27)</td></tr> 65 <tr><td> {</td></tr> 66 <tr><td> //当前图像</td></tr> 67 <tr><td> src = cvQueryFrame(capture);</td></tr> 68 <tr><td> //缩小要处理的图像(减小运算量)</td></tr> 69 <tr><td> cvResize(src, src1, CV_INTER_LINEAR);</td></tr> 70 <tr><td> cvShowImage("src",src1);</td></tr> 71 <tr><td> cvPyrMeanShiftFiltering(src1, src2, pmsf_value, 40, 2);//均值漂移</td></tr> 72 <tr><td> //hsv色彩提取</td></tr> 73 <tr><td onclick="here(‘hand_HSV‘,‘hh‘)"id="hh"> hand_HSV();</td></tr> 74 <tr><td> //降噪</td></tr> 75 <tr><td id="rn"onclick="here(‘reduce_noise‘,‘rn‘)"> reduce_noise();</td></tr> 76 <tr><td> //寻找手轮廓</td></tr> 77 <tr><td id="hc"onclick="here(‘hand_contours‘,‘hc‘)"> hand_contours(smooth1);</td></tr> 78 <tr><td> //寻找匹配</td></tr> 79 <tr><td id="htm"onclick="here(‘hand_template_match‘,‘htm‘)"> hand_template_match(handT, seqMidObj);</td></tr> 80 <tr><td> //求手的移动方向</td></tr> 81 <tr><td id="hd"onclick="here(‘hand_direction‘,‘hd‘)"> hand_direction(seqMidObj);</td></tr> 82 <tr><td> //绘制额外信息</td></tr> 83 <tr><td> cvZero( tmp2 );</td></tr> 84 <tr><td onclick="here(‘hand_draw‘,‘hdr‘)"id="hdr"> hand_draw(tmp2, seqMidObj); //绘制在检测窗口</td></tr> 85 <tr><td onclick="here(‘hand_draw‘,‘hdr2‘)" id="hdr2"> hand_draw(src1, seqMidObj); //绘制在原窗口</td></tr> 86 <tr><td> //cvShowImage( "扩张腐蚀", smooth1);</td></tr> 87 <tr><td> cvShowImage( "最终识别", tmp2 );</td></tr> 88 <tr><td> cvShowImage("src",src1);</td></tr> 89 <tr><td> printf("\n");</td></tr> 90 <tr><td> c = cvWaitKey( 10);</td></tr> 91 <tr><td> }</td></tr> 92 <tr><td> cvReleaseCapture( &capture);</td></tr> 93 <tr><td> cvDestroyAllWindows();</td></tr> 94 <tr><td> return 0;</td></tr> 95 <tr><td> }</td></tr> 96 97 </table> 98 <table id="hand_draw"style="display:none;top:100px;float:left"> 99 <tr><td>void hand_draw(IplImage* dst,CvSeq* hands )</td></tr> 100 <tr><td>{</td></tr> 101 <tr><td> if(!hands) return;</td></tr> 102 <tr><td> CvRect bound;</td></tr> 103 <tr><td> //凸包</td></tr> 104 <tr><td> int i, hullcount;</td></tr> 105 <tr><td> CvPoint pt0;</td></tr> 106 <tr><td> CvSeq* hull;</td></tr> 107 <tr><td> CvSeq* handp = hands;</td></tr> 108 <tr><td> //凸包缺陷</td></tr> 109 <tr><td> CvConvexityDefect* defect;</td></tr> 110 <tr><td> CvSeq* hullDefect;</td></tr> 111 <tr><td> //CvSeq* hullDefectSelect;</td></tr> 112 <tr><td> int hullDefectNum=0;</td></tr> 113 <tr><td> //cvPoint** points = (cvPoint*)malloc(sizeof(cvPoint)*3);</td></tr> 114 <tr><td> //cvPoint points[3];</td></tr> 115 <tr><td> //绘制轮廓</td></tr> 116 <tr><td> cvDrawContours( dst, handp, cvScalar(255,150,100,0),cvScalar(255,0,0,0),1, 1, 8,cvPoint(0,0));</td></tr> 117 <tr><td> </td></tr> 118 <tr><td> CvFont font;</td></tr> 119 <tr><td> //绘制检测到的数字</td></tr> 120 <tr><td> if(if_match_num){</td></tr> 121 <tr><td> </td></tr> 122 <tr><td> //外阴影</td></tr> 123 <tr><td> cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,1.0f,1.0f,0,5,8);</td></tr> 124 <tr><td> cvPutText(dst, num_c[match_num-1], cvPoint(5, 30), &font, CV_RGB(255,255,255)); </td></tr> 125 <tr><td> //内颜色</td></tr> 126 <tr><td> cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,1.0f,1.0f,0,2,8);</td></tr> 127 <tr><td> cvPutText(dst, num_c[match_num-1], cvPoint(5, 30), &font, CV_RGB(255,0,0));</td></tr> 128 <tr><td> }</td></tr> 129 <tr><td> </td></tr> 130 <tr><td> //绘制移动方向</td></tr> 131 <tr><td> if(1){</td></tr> 132 <tr><td> </td></tr> 133 <tr><td> //cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,1.0f,1.0f,0,2,8);</td></tr> 134 <tr><td> //cvPutText(dst, "X: ", cvPoint(5, 30), &font, CV_RGB(255,0,0));</td></tr> 135 <tr><td> </td></tr> 136 <tr><td> }</td></tr> 137 <tr><td> //对提取出的轮廓遍历</td></tr> 138 <tr><td> for( ; handp != 0; handp = handp->h_next ){</td></tr> 139 <tr><td> </td></tr> 140 <tr><td> bound = cvBoundingRect(handp, 0);</td></tr> 141 <tr><td> //求并绘制中心点</td></tr> 142 <tr><td> //内颜色</td></tr> 143 <tr><td> int det = 2;</td></tr> 144 <tr><td> cvRectangle(dst, </td></tr> 145 <tr><td> cvPoint(hand_center.x-det, hand_center.y-det),</td></tr> 146 <tr><td> cvPoint(hand_center.x+det, hand_center.y+det), </td></tr> 147 <tr><td> CV_RGB(0,0,0),3,8,0);</td></tr> 148 <tr><td> //外轮廓</td></tr> 149 <tr><td> det = 3;</td></tr> 150 <tr><td> cvRectangle(dst, </td></tr> 151 <tr><td> cvPoint(hand_center.x-det, hand_center.y-det),</td></tr> 152 <tr><td> cvPoint(hand_center.x+det, hand_center.y+det), </td></tr> 153 <tr><td> CV_RGB(255,255,255),1,8,0);</td></tr> 154 <tr><td> //绘出外包络方框</td></tr> 155 <tr><td> cvRectangle(dst, </td></tr> 156 <tr><td> cvPoint(bound.x, bound.y),</td></tr> 157 <tr><td> cvPoint(bound.x + bound.width, bound.y + bound.height), </td></tr> 158 <tr><td> cvScalar(0,0,255,0),2,8,0);</td></tr> 159 <tr><td> //寻找凸包</td></tr> 160 <tr><td> hull = cvConvexHull2( handp, 0, CV_CLOCKWISE, 0 );</td></tr> 161 <tr><td> hullcount = hull->total;</td></tr> 162 <tr><td> //printf("凸包点数: %d ",hullcount);</td></tr> 163 <tr><td> pt0 = **CV_GET_SEQ_ELEM( CvPoint*, hull, hullcount - 1 );</td></tr> 164 <tr><td> //画凸包</td></tr> 165 <tr><td> for( i = 0; i < hullcount; i++ ){</td></tr> 166 <tr><td> //得到凸包的点</td></tr> 167 <tr><td> CvPoint pt = **CV_GET_SEQ_ELEM( CvPoint*, hull, i );</td></tr> 168 <tr><td> cvLine( dst, pt0, pt, CV_RGB( 0, 255, 0 ), 1, CV_AA, 0 );</td></tr> 169 <tr><td> pt0 = pt;</td></tr> 170 <tr><td> }</td></tr> 171 <tr><td> }</td></tr> 172 <tr><td>}</td></tr> 173 174 </table> 175 <table id="hand_direction"style="display:none;float:left"> 176 <tr><td>//求手的中点和移动方向</td></tr> 177 <tr><td><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> 178 <br /><br /><br /><br /><br /> 179 <br /><br /><br /><br /><br /> 180 <br /><br /><br /><br /><br /> 181 void hand_direction(CvSeq* hand){</td></tr> 182 <tr><td> </td></tr> 183 <tr><td> //如果没有手, 则清除结果</td></tr> 184 <tr><td> if(!hand){</td></tr> 185 <tr><td> hand_center = cvPoint(0,0); </td></tr> 186 <tr><td> hand_center_last = cvPoint(0,0);</td></tr> 187 <tr><td> hand_direct_now = cvPoint(0,0);</td></tr> 188 <tr><td> hand_direct_last = cvPoint(0,0);</td></tr> 189 <tr><td> hand_direct = cvPoint(0,0); </td></tr> 190 <tr><td> return;</td></tr> 191 <tr><td> }</td></tr> 192 <tr><td> </td></tr> 193 <tr><td> hand_center_last = hand_center;</td></tr> 194 <tr><td> //获得中心点</td></tr> 195 <tr><td> CvRect bound = cvBoundingRect(hand, 0);</td></tr> 196 <tr><td> hand_center.x = bound.x + bound.width/2;</td></tr> 197 <tr><td> hand_center.y = bound.y + bound.height/2;</td></tr> 198 <tr><td> if(hand_center_last.x!=0)</td></tr> 199 <tr><td> {</td></tr> 200 <tr><td> hand_direct_now.x = hand_center.x - hand_center_last.x;</td></tr> 201 <tr><td> hand_direct_now.y = hand_center.y - hand_center_last.y;</td></tr> 202 <tr><td> </td></tr> 203 <tr><td> if(hand_direct_now.x!=0)</td></tr> 204 <tr><td> {</td></tr> 205 <tr><td> hand_direct.x = (hand_direct_now.x + hand_direct_last.x)/2;</td></tr> 206 <tr><td> if(hand_direct.x!=0){</td></tr> 207 <tr><td> printf(" X 移动: %d ",hand_direct.x);</td></tr> 208 <tr><td> }</td></tr> 209 <tr><td> </td></tr> 210 <tr><td> }</td></tr> 211 <tr><td> if(hand_direct_now.y!=0){</td></tr> 212 <tr><td> hand_direct.y = (hand_direct_now.y + hand_direct_last.y)/2;</td></tr> 213 <tr><td> if(hand_direct.y!=0){</td></tr> 214 <tr><td> printf(" Y 移动: %d ",hand_direct.y);</td></tr> 215 <tr><td> }</td></tr> 216 <tr><td> }</td></tr> 217 <tr><td> </td></tr> 218 <tr><td> }</td></tr> 219 <tr><td>}</td></tr> 220 221 </table> 222 <table id="hand_template_match"style="display:none;float:left"> 223 <tr><td>//模板匹配手</td></tr> 224 <tr><td><br /><br /><br /><br /><br /> 225 <br /><br /><br /><br /><br /> 226 <br /><br /><br /><br /><br /> 227 <br /><br /><br /><br /><br /> 228 <br /><br /><br /><br /><br /> 229 <br /><br /><br /><br /><br /> 230 <br /><br /><br /><br /><br /> 231 void hand_template_match(CvSeq* handT, CvSeq* hand){</td></tr> 232 <tr><td> int i=0;</td></tr> 233 <tr><td> int kind = -1;</td></tr> 234 <tr><td> double hu = 1;</td></tr> 235 <tr><td> </td></tr> 236 <tr><td> double hutmp;</td></tr> 237 <tr><td> CvSeq* handp = handT;</td></tr> 238 <tr><td> int method = CV_CONTOURS_MATCH_I1;</td></tr> 239 <tr><td> </td></tr> 240 <tr><td> match_num = 0;</td></tr> 241 <tr><td> if(handT==NULL){return;printf("handT==NULL!\n");}</td></tr> 242 <tr><td> if(hand==NULL){return;printf("hand==NULL!\n");}</td></tr> 243 <tr><td> for(i=0; i<handtnum; i++){</td></tr> 244 <tr><td> hutmp = cvMatchShapes(handp, hand, method, 0);</td></tr> 245 <tr><td> handp = handp->h_next;</td></tr> 246 <tr><td> </td></tr> 247 <tr><td> //找到hu矩最小的模板</td></tr> 248 <tr><td> if(hu > hutmp){</td></tr> 249 <tr><td> hu = hutmp;</td></tr> 250 <tr><td> kind = i+1;</td></tr> 251 <tr><td> }</td></tr> 252 <tr><td> </td></tr> 253 <tr><td> //printf("%f ", hu);</td></tr> 254 <tr><td> }</td></tr> 255 <tr><td> </td></tr> 256 <tr><td> //显示匹配结果</td></tr> 257 <tr><td> if(hu<((double)hmatch_value) />100){</td></tr> 258 <tr><td> printf("匹配模板: %d (%f)", kind, hu);</td></tr> 259 <tr><td> match_num = kind;</td></tr> 260 <tr><td> if_match_num = true;</td></tr> 261 <tr><td> }else{</td></tr> 262 <tr><td> if_match_num = false;</td></tr> 263 <tr><td> }</td></tr> 264 <tr><td>}</td></tr> 265 266 </table> 267 <table id="hand_contours"style="display:none;float:left"> 268 <tr><td><br /><br /><br /><br /><br /> 269 <br /><br /><br /><br /><br /> 270 <br /><br /><br /><br /><br /> 271 <br /><br /><br /><br /><br /> 272 <br /><br /><br /><br /><br /> 273 <br /><br /><br /><br /><br /> 274 <br /><br /><br /><br /><br /> 275 <br /><br /><br /><br /><br /> 276 <br /><br /><br /><br /><br /> 277 void hand_contours(IplImage* dst) {</td></tr> 278 <tr><td> if( g_storage==NULL ) {</td></tr> 279 <tr><td> g_storage = cvCreateMemStorage(0);</td></tr> 280 <tr><td> g_storage1 = cvCreateMemStorage(0);</td></tr> 281 <tr><td> g_storage2 = cvCreateMemStorage(0);</td></tr> 282 <tr><td> } else {</td></tr> 283 <tr><td> cvClearMemStorage( g_storage );</td></tr> 284 <tr><td> cvClearMemStorage( g_storage1 );</td></tr> 285 <tr><td> cvClearMemStorage( g_storage2 );</td></tr> 286 <tr><td> }</td></tr> 287 288 </table> 289 <table id="reduce_noise"style="display:none;float:left;top:200px"> 290 <tr><td><br /><br /><br /><br /><br /> 291 <br /><br /><br /><br /><br /> 292 <br /><br /><br /><br /><br /> 293 <br /><br /><br /><br /><br /> 294 <br /><br /><br /><br /><br /> 295 <br /><br /><br /><br /><br /> 296 <br /><br /><br /><br /><br /> 297 <br /><br /><br /><br /><br />void reduce_noise()</td></tr> 298 <tr><td>{</td></tr> 299 <tr><td> cvSmooth(hsv_mask, smooth1, CV_GAUSSIAN, 3, 0, 0, 0);</td></tr> 300 <tr><td> cvSmooth(hsv_mask, smooth1, CV_MEDIAN, 3, 0, 0, 0);</td></tr> 301 <tr><td> cvSmooth(smooth1,smooth1,CV_MEDIAN,3,0,0,0);</td></tr> 302 <tr><td> cvDilate(smooth1, smooth1, 0, 2);</td></tr> 303 <tr><td> cvShowImage( "扩张腐蚀", smooth1);</td></tr> 304 <tr><td>}</td></tr> 305 306 </table> 307 <table id="resizewindow" style="display:none;float:left" > 308 <tr><td> 309 <br /><br /><br /><br /><br /> 310 <br /><br /><br /><br /><br /> 311 <br /><br /> 312 void resizeAllWindow()</td></tr> 313 <tr><td>{</td></tr> 314 <tr><td> cvNamedWindow("src",0);</td></tr> 315 <tr><td> cvNamedWindow( "扩张腐蚀",0);</td></tr> 316 <tr><td> cvNamedWindow( "最终识别",0);</td></tr> 317 <tr><td> cvResizeWindow("src",newSize.width,newSize.height);</td></tr> 318 <tr><td> </td></tr> 319 <tr><td> cvNamedWindow( "参数调试",0);</td></tr> 320 <tr><td> cvResizeWindow("参数调试",newSize.width*1.5,60*11);</td></tr> 321 <tr><td> cvCreateTrackbar( "均值漂移滤波", "参数调试", &pmsf_value, 20, 0 );</td></tr> 322 <tr><td> cvCreateTrackbar( "开运算降噪", "参数调试", &MopEx_value, 5, 0 );</td></tr> 323 <tr><td> cvCreateTrackbar( "色相红黄区", "参数调试", &H_low_max, 150, 0 );</td></tr> 324 <tr><td> cvCreateTrackbar( "色相蓝紫区", "参数调试", &H_high_min, 150, 0 );</td></tr> 325 <tr><td> cvCreateTrackbar( "亮度下限", "参数调试", &V_low, 100, 0 );</td></tr> 326 <tr><td> cvCreateTrackbar( "亮度上限", "参数调试", &V_high, 256, 0 );</td></tr> 327 <tr><td> </td></tr> 328 <tr><td> cvCreateTrackbar( "饱和度下限", "参数调试", &S_low, 100, 0 );</td></tr> 329 <tr><td> cvCreateTrackbar( "饱和度上限", "参数调试", &S_high, 255, 0 );</td></tr> 330 <tr><td> cvCreateTrackbar( "高光补偿", "参数调试", &if_high_light, 1, 0 );</td></tr> 331 <tr><td> cvCreateTrackbar( "match系数", "参数调试", &Hmatch_value, 50, 0 );</td></tr> 332 <tr><td>}</td></tr> 333 334 </table> 335 <table id="init_laplace"style="display:none;float:left"> 336 <tr><td><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> 337 <br /><br /><br /><br /><br /> 338 <br /><br /><br /><br /><br /> 339 <br /><br /><br /><br /><br />void init_laplace()</td></tr> 340 <tr><td>{</td></tr> 341 <tr><td> int i;</td></tr> 342 <tr><td> for( i = 0; i < 3; i++ )</td></tr> 343 <tr><td> planes[i] = cvCreateImage(newSize, 8, 1 );</td></tr> 344 <tr><td> laplace = cvCreateImage( newSize, IPL_DEPTH_16S, 1 );</td></tr> 345 <tr><td> colorlaplace = cvCreateImage( newSize, 8, 3 );</td></tr> 346 <tr><td>}</td></tr> 347 348 </table> 349 <table id="init_hand_YCrCb"style="display:none;float:left"> 350 <tr><td><br /><br /><br /><br /><br /> 351 <br /><br /><br /><br /><br /> 352 <br /><br /><br /><br /><br />void init_hand_YCrCb()</td></tr> 353 <tr><td>{</td></tr> 354 <tr><td> img_YCrCb = cvCreateImage(sz, 8, 3);</td></tr> 355 <tr><td> YCrCb_mask = cvCreateImage(sz, IPL_DEPTH_8U, 1);;</td></tr> 356 <tr><td> /*在人脸检测中也常常用到YCrCb空间,因为一般的图像都是基于RGB空间的, 357 <br/>在RGB空间里人脸的肤色受亮度影响相当大,</td></tr> 358 <tr><td> 所以肤色点很难从非肤色点中分离出来,也就是说在此空间经过处理后, 359 <br/>肤色点是离散的点,中间嵌有很多非肤色,</td></tr> 360 <tr><td> 这为肤色区域标定(人脸标定、眼睛等)带来了难题。 361 <br/>如果把RGB转为YCrCb空间的话,可以忽略Y(亮度)的影响,</td></tr> 362 <tr><td> 因为该空间受亮度影响很小,肤色会产生很好的类聚。 363 <br/>这样就把三维的空间将为二维的CrCb,肤色点会形成一定</td></tr> 364 <tr><td> 得形状,如:人脸的话会看到一个人脸的区域, 365 <br/>手臂的话会看到一条手臂的形态,对处理模式识别很有好处,</td></tr> 366 <tr><td> 根据经验某点的CrCb值满足:133≤Cr≤173,77≤Cb≤127 367 <br/>那么该点被认为是肤色点,其他的就为非肤色点。*/</td></tr> 368 <tr><td> //最终的图片</td></tr> 369 <tr><td> YCrCb = cvCreateImage(sz, IPL_DEPTH_8U, 3);</td></tr> 370 <tr><td> //三通道</td></tr> 371 <tr><td> Y_channel = cvCreateImage(sz, IPL_DEPTH_8U, 1);</td></tr> 372 <tr><td> Cr_channel = cvCreateImage(sz, IPL_DEPTH_8U, 1);</td></tr> 373 <tr><td> Cb_channel = cvCreateImage(sz, IPL_DEPTH_8U, 1);</td></tr> 374 <tr><td> //按范围截取后</td></tr> 375 <tr><td> Y_cmp = cvCreateImage(sz, IPL_DEPTH_8U, 1);</td></tr> 376 <tr><td> Cr_cmp = cvCreateImage(sz, IPL_DEPTH_8U, 1);</td></tr> 377 <tr><td> Cb_cmp = cvCreateImage(sz, IPL_DEPTH_8U, 1);</td></tr> 378 <tr><td> //Y,Cr,Cb的颜色范围</td></tr> 379 <tr><td> Y_lower = CV_RGB(0, 0, 130);</td></tr> 380 <tr><td> Y_upper = CV_RGB(0, 0, 130);</td></tr> 381 <tr><td> Cr_lower = CV_RGB(0, 0, 125);</td></tr> 382 <tr><td> Cr_upper = CV_RGB(0, 0, 125);</td></tr> 383 <tr><td> Cb_lower = CV_RGB(0, 0, 132);</td></tr> 384 <tr><td> Cb_upper = CV_RGB(0, 0, 147);</td></tr> 385 <tr><td> YCrCb_lower = cvScalar(0, 0, 132, 0);</td></tr> 386 <tr><td> YCrCb_upper = cvScalar(130, 125, 147, 0);</td></tr> 387 <tr><td>}</td></tr> 388 </table> 389 <table id="init_hand_HSV"style="display:none;float:left"> 390 <tr><td> 391 <br /><br /><br /><br /><br /> 392 <br /><br /><br /><br /><br /> 393 <br /><br /><br /><br /><br /> 394 <br /><br /><br /><br /><br /> 395 void init_hand_HSV()</td></tr> 396 <tr><td>{</td></tr> 397 <tr><td> hsv_image = cvCreateImage( sz, 8, 3);</td></tr> 398 <tr><td> hsv_mask = cvCreateImage( sz, 8, 1);</td></tr> 399 <tr><td> hsv_min = cvScalar(0, 20, 20, 0);</td></tr> 400 <tr><td> hsv_max = cvScalar(20, 250, 255, 0);</td></tr> 401 <tr><td> //hsv_mask->origin = 1;</td></tr> 402 <tr><td> //方法2: 单独处理各个通道</td></tr> 403 <tr><td> H_img = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 404 <tr><td> S_img = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 405 <tr><td> V_img = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 406 <tr><td> H_mask = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 407 <tr><td> H_mask1 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 408 <tr><td> S_mask = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 409 <tr><td> S_mask1 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 410 <tr><td> V_mask = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 411 <tr><td> V_mask2 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 412 <tr><td> V_mask1 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 413 <tr><td> </td></tr> 414 <tr><td>}</td></tr> 415 416 </table> 417 <table id="inti_threshold"style="display:none;float:left"> 418 <tr><td><br/><br/><br/><br/><br/><br /><br /><br /><br /><br /> 419 <br /><br /><br /><br /><br /> 420 <br /><br /><br /><br /><br /> 421 <br /><br /><br /><br /><br />void inti_threshold()</td></tr> 422 <tr><td>{</td></tr> 423 <tr><td> thd_src = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 424 <tr><td> thd_dst1 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 425 <tr><td> thd_dst2 = cvCreateImage(sz,IPL_DEPTH_8U,1);</td></tr> 426 <tr><td>}</td></tr> 427 428 </table> 429 <table id="hand_HSV"style="display:none;float:left"> 430 <tr><td><br /><br /><br /><br /><br /> 431 <br /><br /><br /><br /><br /> 432 <br /><br /><br /><br /><br /> 433 <br /><br /><br /><br /><br /> 434 <br /><br /><br /><br /><br /> 435 void hand_HSV()</td></tr> 436 <tr><td>{</td></tr> 437 <tr><td> cvCvtColor(src2, hsv_image, CV_BGR2HSV);//均值漂移之后的结果</td></tr> 438 <tr><td> //cvInRangeS (hsv_image, hsv_min, hsv_max, hsv_mask);</td></tr> 439 <tr><td> //cvShowImage( "hsv_msk", hsv_mask);</td></tr> 440 <tr><td> </td></tr> 441 <tr><td> </td></tr> 442 <tr><td> </td></tr> 443 <tr><td> //方法2: 单独处理各个通道</td></tr> 444 <tr><td> cvSplit(hsv_image,H_img,S_img,V_img,0);</td></tr> 445 <tr><td> //color_blance();</td></tr> 446 <tr><td> //cvMerge(H_img,S_img,V_img,0,hsv_image);</td></tr> 447 <tr><td> //cvShowImage( "色彩平衡后", hsv_image);</td></tr> 448 <tr><td> //cvShowImage( "H通道", H_img);</td></tr> 449 <tr><td> </td></tr> 450 <tr><td> </td></tr> 451 <tr><td> //直方图均衡化(效果更差)</td></tr> 452 <tr><td> //cvEqualizeHist(H_img, H_img);</td></tr> 453 <tr><td> </td></tr> 454 <tr><td> //cvShowImage( "H通道_均衡化", H_img);</td></tr> 455 <tr><td> //自适应</td></tr> 456 <tr><td> //cvAdaptiveThreshold(H_img, H_mask, 30, 0, 0, 3, 5);</td></tr> 457 <tr><td> </td></tr> 458 <tr><td> //cvShowImage( "H", H_img);</td></tr> 459 <tr><td> //cvShowImage( "S", S_img);</td></tr> 460 <tr><td> //cvShowImage( "V", V_img);</td></tr> 461 <tr><td> //色相</td></tr> 462 <tr><td> cvInRangeS(H_img,cvScalar(0,0,0,0),cvScalar(H_low_max,0,0,0),H_mask);//红色区</td></tr> 463 <tr><td> cvInRangeS(H_img,cvScalar(256 - H_high_min,0,0,0),cvScalar(256,0,0,0),H_mask1);//紫色区</td></tr> 464 <tr><td> //饱和度</td></tr> 465 <tr><td> cvInRangeS(S_img,cvScalar(S_low,0,0,0),cvScalar(S_high,0,0,0),S_mask); //中间区</td></tr> 466 <tr><td> //cvInRangeS(S_img,cvScalar(20,0,0,0),cvScalar(100,0,0,0),S_mask1); //低饱和度</td></tr> 467 <tr><td> //亮度</td></tr> 468 <tr><td> cvInRangeS(V_img,cvScalar(V_high,0,0,0),cvScalar(256,0,0,0),V_mask);//高亮区</td></tr> 469 <tr><td> cvInRangeS(V_img,cvScalar(V_low,0,0,0),cvScalar(V_high,0,0,0),V_mask1); //中间区</td></tr> 470 <tr><td> //cvInRangeS(V_img,cvScalar(150,0,0,0),cvScalar(250,0,0,0),V_mask2); //较亮区</td></tr> 471 <tr><td> </td></tr> 472 <tr><td> </td></tr> 473 <tr><td> //红黄, 和蓝紫的混合</td></tr> 474 <tr><td> cvOr(H_mask1, H_mask, H_mask, 0);</td></tr> 475 <tr><td> //消除饱和度过低区域</td></tr> 476 <tr><td> cvAnd(H_mask,S_mask,H_mask,0);</td></tr> 477 <tr><td> //cvShowImage( "饱和度过滤", H_mask);</td></tr> 478 <tr><td> //消去过亮过暗区域</td></tr> 479 <tr><td> cvAnd(H_mask,V_mask1,H_mask,0);</td></tr> 480 <tr><td> //cvShowImage( "亮度过滤", H_mask);</td></tr> 481 <tr><td> //cvShowImage( "hsv_msk", H_mask);</td></tr> 482 <tr><td> </td></tr> 483 <tr><td> //补偿过亮区域</td></tr> 484 <tr><td> if(if_high_light) cvOr(H_mask,V_mask,H_mask,0);</td></tr> 485 <tr><td> //cvShowImage( "补偿高光", H_mask);</td></tr> 486 <tr><td> //cvShowImage( "曝光过度 V", V_mask);</td></tr> 487 <tr><td> //cvShowImage( "曝光补偿", S_mask);</td></tr> 488 <tr><td> </td></tr> 489 <tr><td> </td></tr> 490 <tr><td> //是否补偿曝光过度</td></tr> 491 <tr><td> hsv_mask = H_mask;</td></tr> 492 <tr><td> //cvShowImage( "hsv_msk", H_mask);</td></tr> 493 <tr><td> </td></tr> 494 <tr><td>}</td></tr> 495 496 </table> 497 <table id="init_hand_template"style="display:none;float:left"> 498 <tr><td><br /><br /><br /><br /><br /> 499 <br /><br /><br /><br /><br /> 500 <br /><br /><br /><br /><br /> 501 <br /><br /><br /><br /><br /> 502 void init_hand_template()</td></tr> 503 <tr><td>{</td></tr> 504 <tr><td> storage_tmp = cvCreateMemStorage(0);</td></tr> 505 <tr><td> int i = 0;</td></tr> 506 <tr><td> for(i=0; i <handtnum; i++)</td></tr> 507 <tr><td> {</td></tr> 508 <tr><td> tmp_img = cvLoadImage(tmp_names[i], CV_LOAD_IMAGE_GRAYSCALE);</td></tr> 509 <tr><td> if(!tmp_img)</td></tr> 510 <tr><td> {</td></tr> 511 <tr><td> printf("未找到文件: %s\n", tmp_names[i]);</td></tr> 512 <tr><td> continue;</td></tr> 513 <tr><td> }</td></tr> 514 <tr><td> //cvShowImage("载入模板", tmp_img);</td></tr> 515 <tr><td> handT1 = handT2;</td></tr> 516 <tr><td> cvFindContours( tmp_img, storage_tmp, &handT2, sizeof(CvContour), CV_RETR_EXTERNAL);</td></tr> 517 <tr><td> if(handT2){</td></tr> 518 <tr><td> printf("载入模板: %s 成功!\n",tmp_names[i]);</td></tr> 519 <tr><td> if(handT1 == NULL){</td></tr> 520 <tr><td> printf("载入第一个模板!\n");</td></tr> 521 <tr><td> handT = handT2;</td></tr> 522 <tr><td> }else{</td></tr> 523 <tr><td> handT2->h_prev = handT1;</td></tr> 524 <tr><td> handT1->h_next = handT2;</td></tr> 525 <tr><td> }</td></tr> 526 <tr><td> </td></tr> 527 <tr><td> }</td></tr> 528 <tr><td> </td></tr> 529 <tr><td> }</td></tr> 530 <tr><td>}</td></tr> 531 532 </table> 533 </div> 534 </body> 535 </html>
时间: 2024-10-18 11:03:37