OPENCV实现PCA+SVM

        最近在做人脸识别,得到特征向量以后想要再做PCA降维,降维后的结果作为SVM训练的字典。在做PCA降维的过程中遇到一些问题,希望看到的大牛帮忙解决一下,有兴趣的朋友也可以帮忙看看是哪里有问题。

       关于PCA降维的理论就不多说了,网上可以找到很多资料。

       其中有一篇博客是关于用PCA和SVM做人脸识别的http://blog.csdn.net/augusdi/article/details/8865238

我把代码拷贝下来并且简单修改调试后发现有一些问题

#include "opencv/cv.h"
#include "opencv/highgui.h"
#include "opencv/ml.h"
using namespace cv;
using namespace std;

int main(void)
{
	vector<Mat> images;
	char filename[100];
	int imageFaceNum = 100;
	int imageNonFaceNum = 25;
	int num = 0;
	Mat src;
	Mat values(imageFaceNum + imageNonFaceNum, 1, CV_32SC1);
	for (int i = 1; i <= imageFaceNum; i++) {
	sprintf(filename, "E://train_face/%d.jpg", i);
	values.at<int>(i - 1, 0) = 1;
	src = cvLoadImage(filename, 0);
	resize(src,src,Size(48,64));
	images.push_back(src);
	num++;
	}
	for (int i = 1; i <= imageNonFaceNum; i++) {
	sprintf(filename, "E://train_nonface/%d.png", i);
	values.at<int>(num - 1, 0) = 0;
	src = cvLoadImage(filename, 0);
	resize(src, src, Size(48, 64));
	images.push_back(src);
	num++;
	}
	int nEigens = images.size() - 1;
	nEigens = 32;
	Mat desc_mat(images.size(), images[0].rows * images[0].cols, CV_8UC1);
	for (int i = 0; i < images.size(); i++)
	{
	Mat a = images[i].reshape(1, 1) + 0;
	desc_mat.row(i) = images[i].reshape(1,1) + 0;
	}
	Mat average;
	PCA pca(desc_mat, average, CV_PCA_DATA_AS_ROW, nEigens);
	Mat data(desc_mat.rows, nEigens, CV_32FC1);
	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) + 0;
	}

	CvMat d1 = (CvMat)data;
	CvMat d2 = (CvMat)values;
	CvSVM svm;
	CvSVMParams param;
	CvTermCriteria criteria;
	criteria = cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
	param = CvSVMParams(CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria);
	svm.train(&d1, &d2, NULL, NULL, param);
	svm.save("svmdata.xml");

	//
	for (int i = 1; i <= 25; i++) 
	{
	sprintf(filename, "E://train_nonface//%d.png", i);
	src = cvLoadImage(filename, 0);
	resize(src, src, Size(48, 64));
	Mat cs;
	cs = src.reshape(1, 1) + 0;
	Mat average1;

	PCA pca1(cs, average1, CV_PCA_DATA_AS_ROW, nEigens);
	Mat projectedMat(1, nEigens, CV_32FC1);
	projectedMat=pca1.project(cs);
	Mat d3 = projectedMat.row(0) + 0;
	int ret = svm.predict(d3);
	cout << ret << endl;
	}

	return 0;
}

         识别过程中,输入一张图片后得到的cs矩阵的维数是一个只有一行的矩阵,之后做投影得到的projectMat是一个1*1并且值为0的矩阵。而训练过程中训练样本的特征向量是降到32维的,这样就没办法得到和训练过程中和训练样本维数一样的特征向量,这样svm.predict就会有报错,从而得不到识别的结果。

         而只有一行的矩阵求协方差矩阵的特征值分解结果确实是只有一个特征向量和一个特征值,是不能按照PCA理论再降维的,那测试过程中就是要输入一个样本得出测试结果,那应该怎么用PCA降维呢?


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值