加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在OpenCV 2.2中使用C语法的PCA SVM

发布时间:2020-12-16 10:28:47 所属栏目:百科 来源:网络整理
导读:我在使用Mat和PCA类使用最新的C语法使PCA和Eigenfaces工作时遇到了问题.较旧的C语法将Ipl Image *数组作为参数来执行其处理,而当前API仅采用由Column或Row格式化的Mat.我采用了Row方法,使用reshape函数来拟合我的图像矩阵以适合单行.我最终想要获取这些数据
我在使用Mat和PCA类使用最新的C语法使PCA和Eigenfaces工作时遇到了问题.较旧的C语法将Ipl Image *数组作为参数来执行其处理,而当前API仅采用由Column或Row格式化的Mat.我采用了Row方法,使用reshape函数来拟合我的图像矩阵以适合单行.我最终想要获取这些数据然后使用SVM算法来执行检测,但是当我这样做时,我的所有数据都只是一个0流.有人可以帮帮我吗?我究竟做错了什么?谢谢!

我看到this question并且它有点相关,但我不确定解决方案是什么.

这基本上就是我所拥有的:

vector<Mat> images; //This variable will be loaded with a set of images to perform PCA on.
Mat values(images.size(),1,CV_32SC1); //Values are the corresponding values to each of my images.

int nEigens = images.size() - 1; //Number of Eigen Vectors.

//Load the images into a Matrix
Mat desc_mat(images.size(),images[0].rows * images[0].cols,CV_32FC1);
for (int i=0; i<images.size(); i++) {
  desc_mat.row(i) = images[i].reshape(1,1);
}

Mat average;
PCA pca(desc_mat,average,CV_PCA_DATA_AS_ROW,nEigens);

Mat data(desc_mat.rows,nEigens,CV_32FC1); //This Mat will contain all the Eigenfaces that will be used later with SVM for detection

//Project the images onto the PCA subspace
for(int i=0; i<images.size(); i++) {
  Mat projectedMat(1,CV_32FC1);
  pca.project(desc_mat.row(i),projectedMat);

  data.row(i) = projectedMat.row(0);
}

CvMat d1 = (CvMat)data;
CvMat d2 = (CvMat)values;

CvSVM svm;
svm.train(&d1,&d2);
svm.save("svmdata.xml");

解决方法

etarion说的是正确的.

要复制列或行,您必须始终写:

Mat B = mat.col(i);
A.copyTo(B);

以下程序显示了如何在OpenCV中执行PCA.它将显示平均图像和前三个特征脸.我在那里使用的图像可从http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html获得:

#include "cv.h"
#include "highgui.h"

using namespace std;
using namespace cv;

Mat normalize(const Mat& src) {
    Mat srcnorm;
    normalize(src,srcnorm,255,NORM_MINMAX,CV_8UC1);
    return srcnorm;
}

int main(int argc,char *argv[]) {
    vector<Mat> db;

    // load greyscale images (these are from http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html)
    db.push_back(imread("s1/1.pgm",0));
    db.push_back(imread("s1/2.pgm",0));
    db.push_back(imread("s1/3.pgm",0));

    db.push_back(imread("s2/1.pgm",0));
    db.push_back(imread("s2/2.pgm",0));
    db.push_back(imread("s2/3.pgm",0));

    db.push_back(imread("s3/1.pgm",0));
    db.push_back(imread("s3/2.pgm",0));
    db.push_back(imread("s3/3.pgm",0));

    db.push_back(imread("s4/1.pgm",0));
    db.push_back(imread("s4/2.pgm",0));
    db.push_back(imread("s4/3.pgm",0));

    int total = db[0].rows * db[0].cols;

    // build matrix (column)
    Mat mat(total,db.size(),CV_32FC1);
    for(int i = 0; i < db.size(); i++) {
        Mat X = mat.col(i);
        db[i].reshape(1,total).col(0).convertTo(X,CV_32FC1,1/255.);
    }

    // Change to the number of principal components you want:
    int numPrincipalComponents = 12;

    // Do the PCA:
    PCA pca(mat,Mat(),CV_PCA_DATA_AS_COL,numPrincipalComponents);

    // Create the Windows:
    namedWindow("avg",1);
    namedWindow("pc1",1);
    namedWindow("pc2",1);
    namedWindow("pc3",1);

    // Mean face:
    imshow("avg",pca.mean.reshape(1,db[0].rows));

    // First three eigenfaces:
    imshow("pc1",normalize(pca.eigenvectors.row(0)).reshape(1,db[0].rows));
    imshow("pc2",normalize(pca.eigenvectors.row(1)).reshape(1,db[0].rows));
    imshow("pc3",normalize(pca.eigenvectors.row(2)).reshape(1,db[0].rows));

    // Show the windows:
    waitKey(0);
}

如果你想逐行构建矩阵(比如上面的原始问题),请改用:

// build matrix
Mat mat(db.size(),total,CV_32FC1);
for(int i = 0; i < db.size(); i++) {
    Mat X = mat.row(i);
    db[i].reshape(1,1).row(0).convertTo(X,1/255.);
}

并将PCA中的标志设置为:

CV_PCA_DATA_AS_ROW

关于机器学习.我用OpenCV C API写了一篇关于机器学习的文档,其中包含大多数分类器的示例,包括支持向量机.也许你可以在那里得到一些灵感:http://www.bytefish.de/pdf/machinelearning.pdf.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读