gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 19:44:44 27 4
gpt4 key购买 nike

我在使用最新的 C++ 语法与 Mat 和 PCA 类一起使用 PCA 和 Eigenfaces 时遇到了问题。较旧的 C 语法将 IplImage* 数组作为参数来执行其处理,而当前的 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, nEigens, 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, 0, 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, CV_32FC1, 1/255.);
}

并将 PCA 中的标志设置为:

CV_PCA_DATA_AS_ROW

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

关于c++ - 在 OpenCV 2.2 中使用 C++ 语法的 PCA + SVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4974709/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com