Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 如何使用支持向量机进行人员识别?_Opencv_Image Processing_Svm_Face Recognition - Fatal编程技术网

Opencv 如何使用支持向量机进行人员识别?

Opencv 如何使用支持向量机进行人员识别?,opencv,image-processing,svm,face-recognition,Opencv,Image Processing,Svm,Face Recognition,我运行OpenCV 2.4.2C++。< /P> 我正在尝试使用opencv进行人员识别 我使用的是VidTIMIT数据集,其中包含不同方向的不同人员 我正在使用CvSVM对这些人进行分类 我的问题是svm的输出总是相同的 我遵循的算法是: 基于Haar的人脸检测 调整面大小(58*58) 支持向量机训练 分类 现在,我想知道我在训练中是否做错了什么 我正在尝试这种方法,考虑5个(num_name)人,10个(num_图像)不同的图像 void runFaceDetectionRecogniti

我运行OpenCV 2.4.2C++。< /P> 我正在尝试使用opencv进行人员识别

我使用的是VidTIMIT数据集,其中包含不同方向的不同人员

我正在使用CvSVM对这些人进行分类

我的问题是svm的输出总是相同的

我遵循的算法是:

  • 基于Haar的人脸检测
  • 调整面大小(58*58)
  • 支持向量机训练
  • 分类
  • 现在,我想知道我在训练中是否做错了什么

    我正在尝试这种方法,考虑5个(num_name)人,10个(num_图像)不同的图像

    void runFaceDetectionRecognition(vector<Mat_<uchar> > &images){
    vector<vector<Rect> > faces;
    for (unsigned i=0; i<images.size(); ++i) {
    
        /// detection face
        vector<Rect> f;
        faceDetection(images[i], f);
    
        if (!f.empty()) {
            faces.push_back(f);
    
            /// I keep only the face
            Mat_<uchar> roi = ( images[i](f[0]) );
    
            /// resize
            resize(roi, roi, Size(58, 58));
    
            roi.copyTo(images[i]);            
        }
    }
    
    /// Set up parameters
    CvSVMParams params;
    params.svm_type    = CvSVM::C_SVC;
    params.kernel_type = CvSVM::LINEAR;
    params.term_crit   = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
    
    
    /// Set up training data
    float labels[num_name][num_images];
    float label = 0;
    
    /// different label for different person
    for (unsigned i=0; i<num_name; ++i) {
        for (unsigned j=0; j<num_images; ++j)
            labels[i][j] = label;
    
        label++;
    }
    
    /// labeling matrix
    Mat labelsMat(num_name*num_images, 1, CV_32FC1, labels);
    
    /// unrolling images
    float data[images.size()][58*58];
    for (unsigned l=0; l<images.size(); ++l)
    
        for (unsigned i=0; i<58; ++i)
            for (unsigned j=0; j<58; ++j)
                data[l][j+58*i] = images[l].at<float>(i,j);
    
    
    /// training matrix
    Mat train((int) images.size(),58*58, CV_32FC1, data);
    CvSVM svm(train, labelsMat, Mat(), Mat(), params);
    
    /// Validation
    valSVM(svm, train.rowRange(0, 1));
    }
    
    void runFaceDetectionRecognition(矢量和图像){
    向量面;
    
    对于(无符号i=0;i您似乎正在使用完整的58*58面来训练您的支持向量机。为了使支持向量机工作,您需要使用OpenCV中已包含的PCA(主成分分析)等方法来降低维度(获取主成分)

    如果将维数从58*58数组减少到n*n数组,其中n是主要特征,则SVM的训练将仅使用主要特征,并将产生改进的解决方案


    有很多关于OpenCV人脸识别的文档,你可以开始。

    这里的另一个答案是不正确的,说SVM必须使用PCA才能工作。我在没有PCA的128x128图像上使用了SVM,并取得了很好的效果。我用cohn kanade数据集做了类似的事情。下面是一些可能有帮助的源代码

    vector<Mat> preImages;//Fill this with your images from your dataset
    vector<int> labels;//Fill this with the labels from the dataset
    vector<Mat> images;
    
    CascadeClassifier haar_cascade;
    haar_cascade.load("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml");
    vector< Rect_<int> > faces;
    Mat procFace;
    cout << "images: " << preImages.size() << "    labels: " << labels.size() << endl;
    for(unsigned int i = 0; i < preImages.size(); i++)
    {
        procFace = preImages[i].clone();
        //haar_cascade.detectMultiScale(procFace, faces);
        haar_cascade.detectMultiScale(
                procFace,
                faces,
                1.1,
                3,
                CASCADE_FIND_BIGGEST_OBJECT|CASCADE_DO_ROUGH_SEARCH,
                Size(110, 110)
        );
    
        if(faces.size() > 0)
        {
    
            // Process face by face:
            Rect face_i = faces[0];
            // Crop the face from the image.
            Mat face = procFace(face_i);
    
            ////You can maybe use the equalizeHist function here instead//////
            face = illuminationComp(face);
    
            //crop face
            Rect cropped(face_i.width*0.18, face_i.height*0.2, int(face_i.width*0.7), int(face_i.height*0.78));
            Mat Cface = face(cropped);
    
            Mat face_resized;
            resize(Cface, face_resized, Size(128, 128), 1.0, 1.0, INTER_CUBIC);
    
            images.push_back(face_resized);
        }
    }
    
    
    //svm parameters:
    SVMParams params = SVMParams();
    params.svm_type = SVM::C_SVC;
    params.kernel_type = SVM::LINEAR;
    params.degree = 3.43; // for poly
    params.gamma = 0.00225; // for poly / rbf / sigmoid
    params.coef0 = 19.6; // for poly / sigmoid
    params.C = 0.5; // for CV_SVM_C_SVC , CV_SVM_EPS_SVR and CV_SVM_NU_SVR
    params.nu = 0.0; // for CV_SVM_NU_SVC , CV_SVM_ONE_CLASS , and CV_SVM_NU_SVR
    params.p = 0.0; // for CV_SVM_EPS_SVR
    params.class_weights = NULL; // for CV_SVM_C_SVC
    params.term_crit.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
    params.term_crit.max_iter = 1000;
    params.term_crit.epsilon = 1e-6;
    
    if(images.size() == labels.size())
    {
        cout << "Creating SVM Classification" << endl << endl;
    
        int rowsSize = images.size();
        int trainingArea = images[0].rows * images[0].cols;
        Mat trainingMat = Mat::zeros(rowsSize, trainingArea, CV_32FC1);
        int counter;
    
    
        for(int index = 0; index < rowsSize; index++)
        {
            counter = 0;
            for(int rows = 0; rows < images[0].rows; rows++)
            {
                for(int cols = 0; cols < images[0].cols; cols++)
                {
                    trainingMat.at<float>(index, counter) = images[index].at<uchar>(rows,cols);
                        counter++;
                }
            }
        }
    
    
        Mat matLabels = Mat::zeros(labels.size(),1,CV_32FC1);
        for(size_t index = 0; index < labels.size(); index++)
        {
            matLabels.at<float>(index,0) = float(labels[index]);
        }
    
        if(trainingMat.rows == matLabels.rows)
        {
            SVM svm;
            svm.train(trainingMat,matLabels,Mat(),Mat(),params);
            svm.save("svm_model.yml");
        }
    }
    
    vector preImages;//用数据集中的图像填充
    向量标签;//用数据集中的标签填充
    矢量图像;
    级联分类器haar_级联;
    load(“/usr/local/share/OpenCV/haarcascades/haarcascade\u frontalface\u alt.xml”);
    向量<矩形>面;
    垫面;
    
    cout我也在建立一个项目,其中我对一个对象进行了分类。我使用了SVM和Bag of Features(BOf)/BOW的组合。在这种方法中,首先创建字典/代码本,然后训练SVM。结果相当好


    你可以看看这个链接了解一下

    你是否使用原始图像进行训练?它没有特征提取部分。如果我使用LBP提取特征并将其用作SVM训练的输入,怎么样?我是否需要将LBP特征转换为LBP直方图并进行训练?@user8430:提取lpb特征后,你需要计算相应的取消直方图,然后将该直方图向量传递给您的svm分类器。@user8430是的,我使用原始图像进行训练。在训练之前,我做的唯一一件事是对图像运行照明均衡并进行裁剪/对齐。
    vector<Mat> preImages;//Fill this with your images from your dataset
    vector<int> labels;//Fill this with the labels from the dataset
    vector<Mat> images;
    
    CascadeClassifier haar_cascade;
    haar_cascade.load("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml");
    vector< Rect_<int> > faces;
    Mat procFace;
    cout << "images: " << preImages.size() << "    labels: " << labels.size() << endl;
    for(unsigned int i = 0; i < preImages.size(); i++)
    {
        procFace = preImages[i].clone();
        //haar_cascade.detectMultiScale(procFace, faces);
        haar_cascade.detectMultiScale(
                procFace,
                faces,
                1.1,
                3,
                CASCADE_FIND_BIGGEST_OBJECT|CASCADE_DO_ROUGH_SEARCH,
                Size(110, 110)
        );
    
        if(faces.size() > 0)
        {
    
            // Process face by face:
            Rect face_i = faces[0];
            // Crop the face from the image.
            Mat face = procFace(face_i);
    
            ////You can maybe use the equalizeHist function here instead//////
            face = illuminationComp(face);
    
            //crop face
            Rect cropped(face_i.width*0.18, face_i.height*0.2, int(face_i.width*0.7), int(face_i.height*0.78));
            Mat Cface = face(cropped);
    
            Mat face_resized;
            resize(Cface, face_resized, Size(128, 128), 1.0, 1.0, INTER_CUBIC);
    
            images.push_back(face_resized);
        }
    }
    
    
    //svm parameters:
    SVMParams params = SVMParams();
    params.svm_type = SVM::C_SVC;
    params.kernel_type = SVM::LINEAR;
    params.degree = 3.43; // for poly
    params.gamma = 0.00225; // for poly / rbf / sigmoid
    params.coef0 = 19.6; // for poly / sigmoid
    params.C = 0.5; // for CV_SVM_C_SVC , CV_SVM_EPS_SVR and CV_SVM_NU_SVR
    params.nu = 0.0; // for CV_SVM_NU_SVC , CV_SVM_ONE_CLASS , and CV_SVM_NU_SVR
    params.p = 0.0; // for CV_SVM_EPS_SVR
    params.class_weights = NULL; // for CV_SVM_C_SVC
    params.term_crit.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
    params.term_crit.max_iter = 1000;
    params.term_crit.epsilon = 1e-6;
    
    if(images.size() == labels.size())
    {
        cout << "Creating SVM Classification" << endl << endl;
    
        int rowsSize = images.size();
        int trainingArea = images[0].rows * images[0].cols;
        Mat trainingMat = Mat::zeros(rowsSize, trainingArea, CV_32FC1);
        int counter;
    
    
        for(int index = 0; index < rowsSize; index++)
        {
            counter = 0;
            for(int rows = 0; rows < images[0].rows; rows++)
            {
                for(int cols = 0; cols < images[0].cols; cols++)
                {
                    trainingMat.at<float>(index, counter) = images[index].at<uchar>(rows,cols);
                        counter++;
                }
            }
        }
    
    
        Mat matLabels = Mat::zeros(labels.size(),1,CV_32FC1);
        for(size_t index = 0; index < labels.size(); index++)
        {
            matLabels.at<float>(index,0) = float(labels[index]);
        }
    
        if(trainingMat.rows == matLabels.rows)
        {
            SVM svm;
            svm.train(trainingMat,matLabels,Mat(),Mat(),params);
            svm.save("svm_model.yml");
        }
    }