16识别手势(EMD)

16识别手势(EMD)

尝试识别手势。实现例15功能,但是利用EMD匹配策略,本例仅对Compare_Gesture_Hist()函数做了适当修改,具体代码如下:


void Compare_Gesture_Hist(IplImage *sobel1, IplImage *sobel2, IplImage *test, IplImage** canny, IplImage* hist_img)
{
    //建立直方图
    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);        //直方图归一化

    //EMD
    CvMat *sig1, *sig2, *sig_test;
    int numrows = bins;

    sig1 = cvCreateMat(numrows, 2, CV_32FC1);   //numrows行 2列 矩阵
    sig2 = cvCreateMat(numrows, 2, CV_32FC1);
    sig_test = cvCreateMat(numrows, 2, CV_32FC1);

    for (int h = 0; h < bins; h++)
    {
        float bin_val = 0.0;

        bin_val = cvQueryHistValue_1D(hist_model1, h);
        //h:行数 s_bins:总列数(行长度)s:列数  h*s_bins+s 当前bin对应的sig行数   
        cvSet2D(sig1, h, 0, cvScalar(bin_val));
        cvSet2D(sig1, h, 1, cvScalar(h));

        bin_val = cvQueryHistValue_1D(hist_model2, h);
        //h:行数 s_bins:总列数(行长度)s:列数  h*s_bins+s 当前bin对应的sig行数   
        cvSet2D(sig2, h, 0, cvScalar(bin_val));
        cvSet2D(sig2, h, 1, cvScalar(h));

        bin_val = cvQueryHistValue_1D(hist_test, h);
        //h:行数 s_bins:总列数(行长度)s:列数  h*s_bins+s 当前bin对应的sig行数   
        cvSet2D(sig_test, h, 0, cvScalar(bin_val));
        cvSet2D(sig_test, h, 1, cvScalar(h));
    }

    float emd1 = cvCalcEMD2(sig1, sig_test, CV_DIST_L2);
    float emd2 = cvCalcEMD2(sig2, sig_test, CV_DIST_L2);

    printf("EMD距离1:%f; \n", emd1);
    printf("EMD距离2:%f; \n", emd2);

    if ((emd1 <= 1) && (emd2 >= 4))
        {
            cvDrawRect(hist_img, cvPoint(100, 100), cvPoint(200, 200), cvScalar(255, 0, 0), CV_FILLED, 8);
        }
    if ((emd1 >= 1.7) && (emd2 <= 3.4))
        {
            cvDrawRect(hist_img, cvPoint(100, 100), cvPoint(200, 200), cvScalar(0, 0, 255), CV_FILLED, 8);
        }

    printf("\n");
    cout << endl;

    ////比较直方图
    //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 ((value1 <= 0.25) && (value2 >= 0.55))
    //      {
    //          cvDrawRect(hist_img, cvPoint(100, 100), cvPoint(200, 200), cvScalar(255, 0, 0), CV_FILLED, 8);
    //      }
    //      if ((value1 >= 0.45) && (value2 <= 0.4))
    //      {
    //          cvDrawRect(hist_img, cvPoint(100, 100), cvPoint(200, 200), cvScalar(0, 0, 255), CV_FILLED, 8);
    //      }
    //  }
    //  //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");
    //}

结果如下:
这里写图片描述
这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/z827997640/article/details/79841372