//============================================================================ void AAM_TDM::DoPCA(const CvMat* AllTextures, double percentage) { LOGD("Doing PCA of textures datas..."); int nSamples = AllTextures->rows; int nPixels = AllTextures->cols; int nEigenAtMost = MIN(nSamples, nPixels); CvMat* tmpEigenValues = cvCreateMat(1, nEigenAtMost, CV_64FC1); CvMat* tmpEigenVectors = cvCreateMat(nEigenAtMost, nPixels, CV_64FC1); __MeanTexture = cvCreateMat(1, nPixels, CV_64FC1 ); cvCalcPCA(AllTextures, __MeanTexture, tmpEigenValues, tmpEigenVectors, CV_PCA_DATA_AS_ROW); double allSum = cvSum(tmpEigenValues).val[0]; double partSum = 0.0; int nTruncated = 0; double largesteigval = cvmGet(tmpEigenValues, 0, 0); for(int i = 0; i < nEigenAtMost; i++) { double thiseigval = cvmGet(tmpEigenValues, 0, i); if(thiseigval / largesteigval < 0.0001) break; // firstly check(remove small values) partSum += thiseigval; ++ nTruncated; if(partSum/allSum >= percentage) break; //secondly check } __TextureEigenValues = cvCreateMat(1, nTruncated, CV_64FC1); __TextureEigenVectors = cvCreateMat(nTruncated, nPixels, CV_64FC1); CvMat G; cvGetCols(tmpEigenValues, &G, 0, nTruncated); cvCopy(&G, __TextureEigenValues); cvGetRows(tmpEigenVectors, &G, 0, nTruncated); cvCopy(&G, __TextureEigenVectors); cvReleaseMat(&tmpEigenVectors); cvReleaseMat(&tmpEigenValues); LOGD("Done (%d/%d)\n", nTruncated, nEigenAtMost); }
CvMat* PCA(CvMat *Vector1) { int col = Vector1->cols; CvMat* AvgVector; CvMat* EigenValue_Row; CvMat* EigenVector; AvgVector = cvCreateMat(1, col, CV_32FC1); EigenValue_Row = cvCreateMat(col, 1, CV_32FC1); EigenVector = cvCreateMat(col, col, CV_32FC1); //PrintMatrix(Vector1, RED); /* cvCalcPCA() */ cvCalcPCA(Vector1, AvgVector, EigenValue_Row, EigenVector, CV_PCA_DATA_AS_ROW ); PrintMatrix(AvgVector, BLUE); /* cvPorjectPCA() */ cvProjectPCA(Vector1, AvgVector, EigenVector, Vector1); PrintMatrix(Vector1, YELLOW); PrintMatrix(EigenVector, GREEN); /* cvBackProjectPCA */ cvBackProjectPCA(Vector1, AvgVector, EigenVector, Vector1); PrintMatrix(Vector1, BLACK); cvReleaseMat(&AvgVector); cvReleaseMat(&EigenVector); cvReleaseMat(&EigenValue_Row); return Vector1; }
void AAM_Train::shape_pca() { int dimention=2; double resudial=0.98; int ptsNum=shape[0]->ptsNum*dimention; CvMat *pData=cvCreateMat(shapeNum,ptsNum,CV_64FC1); for (int i=0;i<shapeNum;i++) { for (int j=0;j<ptsNum;j++) { //CV_MAT_ELEM(*pData,double,i,j)=shape[i]->ptsForMatlab[j]; //here,we keep the shape in the same scale with the meanshape CV_MAT_ELEM(*pData,double,i,j)=shape[i]->ptsForMatlab[j]; } } s_mean = cvCreateMat(1, ptsNum, CV_64FC1); s_value = cvCreateMat(1, min(shapeNum,ptsNum), CV_64FC1); CvMat *s_PCAvec = cvCreateMat( min(shapeNum,ptsNum), ptsNum, CV_64FC1); cvCalcPCA( pData, s_mean, s_value, s_PCAvec, CV_PCA_DATA_AS_ROW ); double sumEigVal=0; for (int i=0;i<s_value->cols;i++) { sumEigVal+=CV_MAT_ELEM(*s_value,double,0,i); } double sumCur=0; for (int i=0;i<s_value->cols;i++) { sumCur+=CV_MAT_ELEM(*s_value,double,0,i); if (sumCur/sumEigVal>=resudial) { shape_dim=i+1; break; } } //if consider global transform, we will add another 4 shape vector and orthamized? if (isGlobaltransform) { s_vec=cvCreateMat(shape_dim+4,ptsNum,CV_64FC1); for (int i=0;i<shape_dim;i++) { for (int j=0;j<ptsNum;j++) { CV_MAT_ELEM(*s_vec,double,i,j)=CV_MAT_ELEM(*s_PCAvec,double,i,j); } } //add the four shape vectors for (int j=0;j<ptsNum;j++) { CV_MAT_ELEM(*s_vec,double,shape_dim+3,j)=meanShape->ptsForMatlab[j]; if (j<ptsNum/2) { CV_MAT_ELEM(*s_vec,double,shape_dim+2,j)=-meanShape->ptsForMatlab[ptsNum/2+j]; CV_MAT_ELEM(*s_vec,double,shape_dim+1,j)=1; CV_MAT_ELEM(*s_vec,double,shape_dim+0,j)=0; } else { CV_MAT_ELEM(*s_vec,double,shape_dim+2,j)=meanShape->ptsForMatlab[j-ptsNum/2]; CV_MAT_ELEM(*s_vec,double,shape_dim+1,j)=0; CV_MAT_ELEM(*s_vec,double,shape_dim+0,j)=1; } }