14手势梯度方向直方图

xiaoxiao2021-02-28  28

14手势梯度方向直方图

根据输入的手势图像,在每一个区域求取其梯度方向,计算出梯度方向直方图,并可视化。具体代码如下:

#include <cv.h> #include <highgui.h> #include <stdlib.h> #include <stdio.h> #include <math.h> using namespace std; void Create_Hist_1D(IplImage* src, IplImage* canny, IplImage* sobel, IplImage* hist_img); void Compare_Gesture_Hist(IplImage *sobel1, IplImage *sobel2, IplImage *test, IplImage** canny); int main(int argc, char* argv[]) { IplImage *src1, *Isobel1, *Ihist1; //图像 IplImage *src2, *Isobel2, *Ihist2; //图像 IplImage *src3, *Isobel3, *Ihist3; //图像 IplImage *Icanny[3]; if (!(src1 = cvLoadImage("D:\\Template\\OpenCV\\Template57_HOG_Compare\\Debug\\Imask_1.jpg", 0))) return -1; if (!(src2 = cvLoadImage("D:\\Template\\OpenCV\\Template57_HOG_Compare\\Debug\\Imask_2.jpg", 0))) return -2; if (!(src3 = cvLoadImage("D:\\Template\\OpenCV\\Template57_HOG_Compare\\Debug\\DST.jpg", 0))) return -3; Icanny[0] = cvCreateImage(cvSize(src1->width, src1->height), 8, 1); //canny图像 深度8 Icanny[1] = cvCreateImage(cvSize(src2->width, src2->height), 8, 1); Icanny[2] = cvCreateImage(cvSize(src3->width, src3->height), 8, 1); Isobel1 = cvCreateImage(cvSize(src1->width, src1->height), 32, 1); Isobel2 = cvCreateImage(cvSize(src2->width, src2->height), 32, 1); Isobel3 = cvCreateImage(cvSize(src3->width, src3->height), 32, 1); Ihist1 = cvCreateImage(cvSize(320, 300), 8, 3); //320*320 Ihist2 = cvCreateImage(cvSize(320, 300), 8, 3); //320*320 Ihist3 = cvCreateImage(cvSize(320, 300), 8, 3); //320*320 Create_Hist_1D(src1, Icanny[0], Isobel1, Ihist1); Create_Hist_1D(src2, Icanny[1], Isobel2, Ihist2); Create_Hist_1D(src3, Icanny[2], Isobel3, Ihist3); Compare_Gesture_Hist(Isobel1, Isobel2, Isobel3, Icanny); cvNamedWindow("SRC1", 1); cvNamedWindow("SRC2", 2); cvNamedWindow("SRC3", 3); //cvNamedWindow("Canny_1", 1); //cvNamedWindow("Canny_2", 1); //cvNamedWindow("Canny_3", 1); cvNamedWindow("SOBEL_1", 1); cvNamedWindow("SOBEL_2", 1); cvNamedWindow("SOBEL_3", 1); cvNamedWindow("Hist_1", 1); cvNamedWindow("Hist_2", 1); cvNamedWindow("Hist_3", 1); cvShowImage("SRC1", src1); cvShowImage("SRC2", src2); cvShowImage("SRC3", src3); //cvShowImage("Canny_1", Icanny[0]); //cvShowImage("Canny_2", Icanny[1]); //cvShowImage("Canny_3", Icanny[2]); cvShowImage("SOBEL_1", Isobel1); cvShowImage("SOBEL_2", Isobel2); cvShowImage("SOBEL_3", Isobel3); cvShowImage("Hist_1", Ihist1); cvShowImage("Hist_2", Ihist2); cvShowImage("Hist_3", Ihist3); cvWaitKey(); cvReleaseImage(&src1); cvReleaseImage(&src2); cvReleaseImage(&src3); cvReleaseImage(&Icanny[0]); cvReleaseImage(&Icanny[1]); cvReleaseImage(&Icanny[2]); cvReleaseImage(&Isobel1); cvReleaseImage(&Isobel2); cvReleaseImage(&Isobel3); cvReleaseImage(&Ihist1); cvReleaseImage(&Ihist2); cvReleaseImage(&Ihist3); cvDestroyAllWindows(); } void Create_Hist_1D(IplImage* src, IplImage* canny, IplImage* gradient_dir, IplImage* hist_img) { IplImage *sobel_x, *sobel_y; sobel_x = cvCreateImage(cvSize(src->width, src->height), 32, 1); sobel_y = cvCreateImage(cvSize(src->width, src->height), 32, 1); //边缘检测 src dst 边缘连接 边缘初始分割 核 cvCanny(src, canny, 60, 180, 3); //方向导数 cvSobel(src, sobel_x, 1, 0, 3); //横向梯度dx cvSobel(src, sobel_y, 0, 1, 3); //纵向梯度dy //梯度方向 dy/dx cvDiv(sobel_y, sobel_x, gradient_dir); //梯度方向 char* ptr = NULL; float theta=0.0; //梯度方向角 ptr = gradient_dir->imageData; if (ptr != NULL) { for (int i = 0; i < gradient_dir->height; i++) //矩阵指针行寻址 { ptr = (gradient_dir->imageData + i*(gradient_dir->widthStep)); //i 行 j 列 for (int j = 0; j < gradient_dir->width; j++) //矩阵指针列寻址 { if (cvGetReal2D(canny, i, j) && cvGetReal2D(sobel_x, i, j)) //dx!=0 { theta = cvGetReal2D(gradient_dir, i, j); theta = atan(theta); cvSetReal2D(gradient_dir, i, j, theta); } else //dx=0 { cvSetReal2D(gradient_dir, i, j, 0); } } } } float max = 0.0; int bins = 20; int hist_size[] = { bins }; //对应维数包含bins个数的数组 float range[] = { -CV_PI / 2, CV_PI / 2 }; float* ranges[] = { range }; CvHistogram* hist = cvCreateHist(1, hist_size, CV_HIST_ARRAY, ranges, 1); cvZero(hist_img); IplImage *planes[] = { gradient_dir }; //梯度图像数组 cvCalcHist(planes, hist, 0, canny); //只计算边界直方图 cvGetMinMaxHistValue(hist, 0, &max, 0, 0); cvConvertScale(hist->bins, hist->bins, max ? 255. / max : 0., 0); //缩放bin到[0,255] double bin_width = (double)hist_img->width / bins * 3 / 4; for (int i = 0; i<bins; i++) { double val = cvGetReal1D(hist->bins, i)*hist_img->height / 255; CvPoint p0 = cvPoint(30 + i*bin_width, hist_img->height); CvPoint p1 = cvPoint(30 + (i + 1)*bin_width, hist_img->height - val); cvRectangle(hist_img, p0, p1, cvScalar(0, 255), 1, 8, 0); } cvReleaseHist(&hist); //释放直方图 cvReleaseImage(&sobel_x); cvReleaseImage(&sobel_y); } void Compare_Gesture_Hist(IplImage *sobel1, IplImage *sobel2, IplImage *test, IplImage** canny) { //建立直方图 CvHistogram *hist_model1, *hist_model2, *hist_test; int bins = 20; int hist_size[] = { bins }; //对应维数包含bins个数的数组 float range[] = { -CV_PI / 2, CV_PI / 2 }; float* ranges[] = { range }; //划分范围数对, ****均匀bin,range只要最大最小边界 //创建直方图 (维数,对应维数bins个数,密集矩阵方式存储,划分范围数对,均匀直方图) hist_model1 = cvCreateHist(1, hist_size, CV_HIST_ARRAY, ranges, 1); hist_model2 = cvCreateHist(1, hist_size, CV_HIST_ARRAY, ranges, 1); hist_test = cvCreateHist(1, hist_size, CV_HIST_ARRAY, ranges, 1); IplImage *planes1[] = { sobel1 }; IplImage *planes2[] = { sobel2 }; IplImage *planes3[] = { test }; cvCalcHist(planes1, hist_model1, 0, canny[0]); //计算直方图(图像,直方图结构,不累加,掩码) cvCalcHist(planes2, hist_model2, 0, canny[1]); //计算直方图(图像,直方图结构,不累加,掩码) cvCalcHist(planes3, hist_test, 0, canny[2]); //计算直方图(图像,直方图结构,不累加,掩码) cvNormalizeHist(hist_model1, 1.0); //直方图归一化 cvNormalizeHist(hist_model2, 1.0); //直方图归一化 cvNormalizeHist(hist_test, 1.0); //直方图归一化 //比较直方图 for (int j = 0; j < 4; j++) { double value1 = cvCompareHist(hist_test, hist_model1, j); //相关方式比较 double value2 = cvCompareHist(hist_test, hist_model2, j); //相关方式比较 if (j == 0) { std::printf(" Hist_test & Hist_model1 ,CV_COMP_CORREL: %lf;\n", value1); std::printf(" Hist_test & Hist_model2 ,CV_COMP_CORREL: %lf;\n", value2); } if (j == 1) { std::printf(" Hist_test & Hist_model1 ,CV_COMP_CHISQR: %lf;\n", value1); std::printf(" Hist_test & Hist_model2 ,CV_COMP_CHISQR: %lf;\n", value2); } if (j == 2) { std::printf(" Hist_test & Hist_model1 ,CV_COMP_INTERSECT: %lf;\n", value1); std::printf(" Hist_test & Hist_model2 ,CV_COMP_INTERSECT: %lf;\n", value2); } if (j == 3) { std::printf(" Hist_test & Hist_model1 ,CV_CCOMP_BHATTACHARYYA: %lf;\n", value1); std::printf(" Hist_test & Hist_model2 ,CV_CCOMP_BHATTACHARYYA: %lf;\n", value2); } std::printf("\n"); } cvReleaseHist(&hist_model1); cvReleaseHist(&hist_model2); cvReleaseHist(&hist_test); }

运行结果:

转载请注明原文地址: https://www.6miu.com/read-2400003.html

最新回复(0)