邊緣梯度方向直方圖的構建


在手勢識別時,可利用模板手勢與當前手勢的邊緣梯度方向直方圖進行匹配來識別當前手勢, 故而就需要構建圖像的邊緣梯度方向直方圖.

梯度為:dx*dx+dy*dy開方.            

梯度方向則為:dy/dx(注意dx為0的情況處理).

 1 #include "stdafx.h"
 2 #include "cv.h"
 3 #include "highgui.h"
 4 
 5 int main()
 6 {
 7     IplImage* src=cvLoadImage("C:/Users/shark/Desktop/fruits.jpg",0);
 8     CvSize size=cvGetSize(src);
 9     //邊緣檢測
10     IplImage* canny=cvCreateImage(size,8,1);
11     IplImage* canny32=cvCreateImage(size,IPL_DEPTH_32F,1);
12     cvCanny(src,canny,60,180,3);
13     cvConvert(canny,canny32);
14     //梯度計算
15     IplImage* dx=cvCreateImage(size,IPL_DEPTH_16S,1);
16     IplImage* dy=cvCreateImage(size,IPL_DEPTH_16S,1);
17     cvSobel(src,dx,1,0,3);
18     cvSobel(src,dy,0,1,3);
19     IplImage* dx32=cvCreateImage(size,IPL_DEPTH_32F,1);
20     IplImage* dy32=cvCreateImage(size,IPL_DEPTH_32F,1);
21     cvConvert(dx,dx32);
22     cvConvert(dy,dy32);
23     IplImage* gradient=cvCreateImage(size,IPL_DEPTH_32F,1);       //梯度圖像
24     IplImage* gradient_dir=cvCreateImage(size,IPL_DEPTH_32F,1);   //梯度方向圖像
25     cvDiv(dx32,dy32,gradient_dir);
26   
27     cvMul(dx32,dx32,dx32,1.0);
28     cvMul(dy32,dy32,dy32,1.0);
29     cvAdd(dx32,dy32,gradient,0);
30     for(int i=0;i<size.height;i++)
31         for(int j=0;j<size.width;j++)
32         {
33             gradient->imageData[i*gradient->widthStep+j]=cvSqrt((float)
34 
35                 gradient->imageData[i*gradient->widthStep+j]);
36         }
37       float theta;
38         for(int i=0;i<size.height;i++)
39             for(int j=0;j<size.width;j++)
40             {
41                 if(cvGetReal2D(canny32,i,j)!=0 && cvGetReal2D(dx32,i,j)!=0)    
42 
43                     //dy/dx中dx!=0
44                 {
45                     theta=cvGetReal2D(gradient_dir,i,j);
46                     theta=atan(theta);
47                     cvSetReal2D(gradient_dir,i,j,theta);
48                 }
49                 else
50                 {
51                     cvSetReal2D(gradient_dir,i,j,0);
52                 }
53             }
54             int bins=20; float max=0;
55             float range[]={-CV_PI/2,CV_PI/2};
56             float* ranges[]={range};
57             CvHistogram* hist=cvCreateHist(1,&bins,CV_HIST_ARRAY,ranges,1);
58             IplImage* hist_img=cvCreateImage(cvSize(320,200),8,3);
59             cvZero(hist_img);
60             cvCalcHist(&gradient_dir,hist,0,canny);                       //只計算邊界直方圖
61             cvGetMinMaxHistValue(hist,0,&max,0,0);
62             cvConvertScale(hist->bins,hist->bins,max?255./max:0.,0);   //縮放bin到[0,255]
63             double bin_width=(double)hist_img->width/bins*3/4;
64             for(int i=0;i<bins;i++)
65             {
66                 double val=cvGetReal1D(hist->bins,i)*hist_img->height/255;
67                 CvPoint p0=cvPoint(30+i*bin_width,hist_img->height);
68                 CvPoint p1=cvPoint(30+(i+1)*bin_width,hist_img->height-val);
69                 cvRectangle(hist_img,p0,p1,cvScalar(0,255),1,8,0);
70             }
71             cvNamedWindow("hist_img");
72             cvShowImage("hist_img",hist_img);
73             cvWaitKey();
74 
75 
76 }

原圖:

梯度方向直方圖:


免責聲明!

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



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