当前位置: 首页 > 知识库问答 >
问题:

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

姚自强
2023-03-14

我运行的是opencv 2.4.2C++。

我试图用OpenCV来识别人。

我正在使用VidTIMIT数据集,该数据集包含不同方向的不同人员。

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

我的问题是SVM的输出总是一样的。

我遵循的算法是:

  1. 基于Haar的人脸检测
  2. 调整面的大小(58*58)
  3. 支持向量机训练
  4. 分类

现在,我在想我是不是在训练中做错了什么。

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

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 valSVM(CvSVM &svm, Mat train){

/// prediction
float response = svm.predict(train);

cout << "Response ===> " << response << " ";

/// output
if (response == 0)  cout << "lea";
else if (response == 1)  cout << "maria";
else if (response == 2)  cout << "ramona";
else if (response == 3)  cout << "teresa";
else if (response == 4)  cout << "yan";
}

希望你能帮助我。

共有1个答案

笪德华
2023-03-14

这里的另一个答案是不正确的,说支持向量机必须使用PCA来发挥作用。在没有PCA的128×128幅图像上使用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");
    }
}
 类似资料:
  • 选取出关键特征 通过tf-idf计算出来的数值是某个特征(词)对于这篇文档的权重,不代表这个特征(词)在文本分类中的权重。这很容易理解,比如某一个特征(词)在多个分类中的tf-idf是不一样的,但是这个特征对于这个分类问题的权重肯定是一个定值。 选取重要的特征的方法可以是:1.)按tf-idf排序从大到小选topN;2)按特征的普遍性选取(在多个类别中出现过);3)按特征在不同文档中tf-idf的

  • 支持向量机 概述 支持向量机(Support Vector Machines, SVM):是一种监督学习算法。 支持向量(Support Vector)就是离分隔超平面最近的那些点。 机(Machine)就是表示一种算法,而不是表示机器。 支持向量机 场景 要给左右两边的点进行分类 明显发现:选择D会比B、C分隔的效果要好很多。 支持向量机 原理 SVM 工作原理 对于上述的苹果和香蕉,我们想象为

  • 支持向量机(Support Vector Machine,SVM它是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,学习策略是间隔最大化,最终可转化为一个凸二次规划问题的求解。 直观来看,位于两类训练样本“正中间”的划分超平面效果最好,即中间最粗的那条。 一般使用支持向量机时还会使用核函数,这样支持向量机会成为实质上的非线性分类器。 基本概念 在样本空间中,划分超平面可以定义为

  • 利用CoreImage进行人脸识别,可以判断人脸整体位置,以及两只眼睛和嘴巴的大概位置。并根据人脸范围,对图片进行剪切。 [Code4App.com]

  • 综述 “看二更云,三更月,四更天。” 本文采用编译器:jupyter    给定训练样本集D,分类学习最基本的想法就是基于训练集D的样本空间中找到一个划分超平面,将不同类别的样本分开。但能将训练样本分开但划分超平面可能有很多,如图。 存在多个划分超平面将两类训练样本分开 直观上看,应该去找位于两类训练样本"正中间"的划分超平面,即图中粗线的那个,因为该划分超平面对训练样本局部扰动的"容忍性"最好。

  • 支持向量机(SVM)是个非常强大并且有多种功能的机器学习模型,能够做线性或者非线性的分类,回归,甚至异常值检测。机器学习领域中最为流行的模型之一,是任何学习机器学习的人必备的工具。SVM 特别适合应用于复杂但中小规模数据集的分类问题。 本章节将阐述支持向量机的核心概念,怎么使用这个强大的模型,以及它是如何工作的。 线性支持向量机分类 SVM 的基本思想能够用一些图片来解释得很好,图 5-1 展示了