zoukankan      html  css  js  c++  java
  • OpenCV——手势识别

    使用ANN神经网络训练数据后进行手势识别。

    #include "header.h"
    
    
    int main()
    {
        const int sample_num = 10;              //训练每类图片数量
        const int class_num = 3;                //训练类数3:石头剪刀布
        const int image_cols = 30;
        const int image_rows = 30;
        string  Name, Path;
    
        float trainingData[class_num * sample_num][image_cols * image_rows] = { { 0 } };       //每一行一个训练样本
        float labels[class_num * sample_num][class_num] = { { 0 } };                           //训练样本标签
    
        cout << "training Data.........
    ";
        for (int i = 0; i < class_num; i++){
    
            int j = 0;
            Path = getstring(i + 1) + "/" + "*.*";
    
            HANDLE hFile;
            LPCTSTR lp = StringToWchar(Path);
            WIN32_FIND_DATA pNextInfo;
            hFile = FindFirstFile(lp, &pNextInfo);
            if (hFile == INVALID_HANDLE_VALUE){
                cout << "failed" << endl;
                exit(-1);//搜索失败
            }
            cout << "folder name:" << i + 1 << endl;
            
            do{
                //必须加这句,不然会加载.和..的文件而加载不了图片,
                if (pNextInfo.cFileName[0] == '.')continue;   
    
                cout << "file name" << WcharToChar(pNextInfo.cFileName) << endl;
                Mat srcImage = imread(getstring(i+1) + "/" + WcharToChar(pNextInfo.cFileName), CV_LOAD_IMAGE_GRAYSCALE);
                Mat trainImage;
                
                //if (!srcImage.empty())cout << " done 
    ";
                //处理样本图像
                resize(srcImage, trainImage, Size(image_cols, image_rows), (0, 0), (0, 0), CV_INTER_AREA); 
                Canny(trainImage, trainImage, 150, 100, 3, false);
                for (int k = 0; k < image_rows * image_cols; k++){
                    //cout << "矩阵 k-- " << k << "   j--" << j << "   i--" << i << endl;
                    trainingData[i*sample_num + j][k] = (float)trainImage.data[k];
    
                }
                j++;
            } while (FindNextFile(hFile, &pNextInfo));
        }
    
        // 训练好的矩阵
        Mat DataMat(class_num*sample_num, image_rows*image_cols, CV_32FC1, trainingData);
        cout << "DataMat   done~" << endl;
    
        // 初始化标签 
        // 0-石头 1-剪刀 2-布
        for (int i = 0; i < class_num ; i++){
            for (int j = 0; j < sample_num; j++){
                for (int k = 0; k < class_num; k++){
                    if (k == i)labels[i*sample_num + j][k] = 1;
                    else labels[i*sample_num + j][k] = 0;
                }
            }
        }
    
        // 标签矩阵
        Mat labelsMat(class_num*sample_num, class_num, CV_32FC1, labels);
        cout << "labelsMat  done~" << endl;
    
        //训练代码
        CvANN_MLP bp;
        CvANN_MLP_TrainParams params;
        params.train_method = CvANN_MLP_TrainParams::BACKPROP;
        params.bp_dw_scale = 0.001;    
        params.bp_moment_scale = 0.1;
        //cvTermCriteria 迭代终止规则
        params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10000, 0.0001);     
    
        //设置网络层数
        Mat layerSizes = (Mat_<int>(1, 4) << image_rows*image_cols, int(image_rows*image_cols / 2), 
                                                                     int(image_rows*image_cols / 2), class_num);
        bp.create(layerSizes, CvANN_MLP::SIGMOID_SYM, 1.0, 1.0);     
        cout << "training...." << endl;
        bp.train(DataMat, labelsMat, Mat(), Mat(), params);
    
        bp.save("detect_gesture.xml"); 
        cout << "done" << endl;
    
        //测试神经网络
        cout << "testing...." << endl;
    
        Mat test = imread("test.jpg");   
        Mat temp;
        resize(test, temp, Size(image_cols, image_rows), (0, 0), (0, 0), CV_INTER_AREA);
        Canny(temp, temp, 150, 100, 3, false);
        Mat_<float>sample(1, image_rows*image_cols);
        for (int i = 0; i<image_rows*image_cols; ++i){
            sample.at<float>(0, i) = (float)temp.data[i];
        }
    
        Mat result;
        bp.predict(sample, result);
    
        float* p = result.ptr<float>(0);
        float max = -1, min = 0;
        int index = 0;
        for (int i = 0; i<class_num; i++)
        {
            cout << (float)(*(p + i)) << " ";
            if (i == class_num - 1)
                cout << endl;
            if ((float)(*(p + i))>max)
            {
                min = max;
                max = (float)(*(p + i));
                index = i;
            }
            else
            {
                if (min < (float)(*(p + i)))
                    min = (float)(*(p + i));
            }
        }
        cout << "Your choice :" << choice[index] << endl << "识别率:" 
                                                  << (((max - min) * 100) > 100 ? 100 : ((max - min) * 100)) << endl;
    
        
        //石头剪刀布——游戏开局~
        int computer = random(3);
        cout << "computer's choice :" << choice[computer] << endl;
        if (computer == index) cout << "A Draw   -_- " << endl << endl;
        else if ((computer < index && (index - computer == 1)) || (computer == 2 && index == 0)){
            cout << "You Lose  T_T " << endl << endl;
        }
        else cout << "You Win o   * ̄▽ ̄* " << endl << endl;
    
        system("pause");
        waitKey(100);
        return 0;
    }

     运行一次后,不用每次都训练数据,直接加载第一次保存的 "detect_gesture.xml"即可

    CvANN_MLP bp;
    CvANN_MLP_TrainParams params;
    bp.load("detect_gesture.xml");

    PS:

    //CvTermCriteria()
    //迭代算法的终止准则
    #define CV_TERMCRIT_ITER    1
    #define CV_TERMCRIT_NUMBER  CV_TERMCRIT_ITER
    #define CV_TERMCRIT_EPS     2
    
    typedef struct CvTermCriteria
     {
      int    type;                      // CV_TERMCRIT_ITER 和CV_TERMCRIT_EPS二值之一,或者二者的组合 
      int    max_iter;                  // 最大迭代次数 
      double epsilon;                   // 结果的精确性 
     }
     CvTermCriteria;
    // 构造函数 
    inline  CvTermCriteria  cvTermCriteria( int type, int max_iter, double epsilon );
    // 在满足max_iter和epsilon的条件下检查终止准则并将其转换使得type=CV_TERMCRIT_ITER+CV_TERMCRIT_EPS 
    CvTermCriteria cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, int default_max_iters );

     文件查找相关

  • 相关阅读:
    [WPF系列] window自定义
    [WPF系列]-Prism+EF
    C#基础-事件 继承类无法直接引发基类的事件
    [WPF系列] 高级 调试
    [WPF系列]-DynamicResource与StaticResource的区别
    [WPF系列]-DataBinding 绑定计算表达式
    [WPF系列]- Style
    [WPF系列]-基础 TextBlock
    [WPF系列]-ListBox
    [WPF系列]-DataBinding 枚举类型数据源
  • 原文地址:https://www.cnblogs.com/farewell-farewell/p/6031314.html
Copyright © 2011-2022 走看看