1、PCA Class Introduction----C++
class PCA
{
public:
// default constructor
PCA();
// computes PCA for a set of vectors stored as data rows or columns.
PCA(const Mat& data, const Mat& mean, int flags, int maxComponents=0);
// computes PCA for a set of vectors stored as data rows or columns
PCA& operator()(const Mat& data, const Mat& mean, int flags, int maxComponents=0);
// projects vector into the principal components space
Mat project(const Mat& vec) const;
void project(const Mat& vec, Mat& result) const;
// reconstructs the vector from its PC projection
Mat backProject(const Mat& vec) const;
void backProject(const Mat& vec, Mat& result) const;
// eigenvectors of the PC space, stored as the matrix rows
Mat eigenvectors;
// the corresponding eigenvalues; not used for PCA compression/decompression
Mat eigenvalues;
// mean vector, subtracted from the projected vector
// or added to the reconstructed vector
Mat mean;
};
注:PCA constructors 补充说明
PCA::PCA(const Mat& data, const Mat& mean, int flags, int maxComponents=0)
Parameters:
l data – the input samples, stored as the matrix rows or as the matrix columns
l mean – the optional mean value. If the matrix is empty ( Mat() ), the mean is computed from the data.
l flags –
operation flags. Currently the parameter is only used to specify the data layout.
ü CV_PCA_DATA_AS_ROWS Indicates that the input samples are stored as matrix rows.
ü CV_PCA_DATA_AS_COLS Indicates that the input samples are stored as matrix columns.
l maxComponents – The maximum number of components that PCA should retain. By default, all the components are retained.
PCA Class Test
PCA compressPCA(const Mat& pcaset, int maxComponents, const Mat& testset, Mat& compressed)
{
PCA pca(pcaset, // pass the data
Mat(),// we do not have a pre-computed mean vector,
// so let the PCA engine to compute it
CV_PCA_DATA_AS_ROW,// indicate that the vectors
// are stored as matrix rows
// (use CV_PCA_DATA_AS_COL if the vectors are
// the matrix columns)
maxComponents// specify, how many principal components to retain
);
// if there is no test data, just return the computed basis, ready-to-use
if( !testset.data )
return pca;
CV_Assert( testset.cols == pcaset.cols );
compressed.create(testset.rows, maxComponents, testset.type());
Mat reconstructed;
for( int i = 0; i < testset.rows; i++ )
{
Mat vec = testset.row(i), coeffs = compressed.row(i);
// compress the vector, the result will be stored
// in the i-th row of the output matrix
pca.project(vec, coeffs);
// and then reconstruct it
pca.backProject(coeffs, reconstructed);
// and measure the error
printf("
}
return pca;
}
2、 PCA
//初始化数据
CvMat* pData = cvCreateMat( 总的样本数, 每个样本的维数, CV_32FC1 ); //每一行表示一个样本
CvMat* pMean = cvCreateMat(1, 样本的维数, CV_32FC1);
CvMat* pEigVals = cvCreateMat(1, 样本的维数, CV_32FC1); //pEigVals中的每个数表示一个特征值
CvMat* pEigVecs = cvCreateMat( 样本的维数, 样本的维数, CV_32FC1); //每一行表示一个特征向量
//PCA处理,计算出平均向量pMean,特征值pEigVals和特征向量pEigVecs
cvCalcPCA( pData, pMean, pEigVals, pEigVecs, CV_PCA_DATA_AS_ROW );
//选出前P个特征向量(主成份),然后投影,结果保存在pResult中
CvMat* pResult = cvCreateMat( 总的样本数, PCA变换后的样本维数(即主成份的数目), CV_32FC1 );
cvProjectPCA( pData, pMean, pEigVecs, pResult );
//重构,结果保存在pRecon中
CvMat* pRecon = cvCreateMat( 总的样本数, 每个样本的维数, CV_32FC1 );
cvBackProjectPCA( pResult, pMean, pEigVecs, pRecon );
//重构误差的计算
//计算pRecon和pData的"差"就可以了.
附:读取矩阵pData中第i行的第j个元素的方法:cvmGet( pData, i, j ).
3、CvvImage
利用CvvImage可以方便地在MFC中画图(DrawToHdc函数),但是在调用Copyof这个函数时,要写成
CvvImage img;
IplImage src;
img.Copyof( src, src->nChannels),
否则,如果写成img.Copyof(src),src是单通道的话,会出现错误!
CvvImage不仅能处理3通道,也能处理单通道。
4、IplImage和CvMat的相互转化
IplImage* img = cvLoadImage( "d:\\1.jpg" );
CvMat matHearder;
CvMat* mat = cvGetMat( img, &matHearder );
int i;
for( i = 0; i < 10; i++ )
printf( "%d ", (u_char)img->imageData[i] );
printf( "\n" );
for( i = 0; i < 10; i++ )
printf( "%d ", mat->data.ptr[i] );
注意:(1)有些函数并不会自动将IplImage转化为CvMat,如pca和svd的相关函数。
(2)上述转换后mat中元素的范围为[0,255],img的范围是[-128,127].
(3)要把img中的数据转换成无符号整数时,需要强制类型转换 u_char;