Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

cvCalcEigenObjects in opencv?

Here's my code:

#include "StdAfx.h"
#include <stdio.h>
#include "cv.h"
#include "highgui.h"
#include "cvaux.h"
#include "legacy.h"
/*************************************************/
//Global variables
int nTrainFaces = 0;//number of training images
int nEigens = 0;//number of eigenvalues
IplImage** faceImgArr = 0;//array of face images
IplImage** eigenVectArr = 0;//eigenvectors
CvMat* personNumTruthMat;
CvMat* projectedTrainFaceMat;//projected training faces
CvMat* eigenValMat;//eigenvalues
IplImage* pAvgTrainImg = 0;
/*************************************************/
//Define methods
void learn();
int loadFaceImgArray(char* filename);
void doPCA();
void storeTrainingData();
void recognize();
int loadTrainingData(CvMat** pTrainPersonNumMat);
int findNearestNeighbor(float* projectedTestFace);
/*************************************************/
//Content of methods
void learn()
{
int i;
//load training data
nTrainFaces = loadFaceImgArray("training_images.txt");
//do PCA on the training faces
doPCA();
//project the training images onto the PCA subspace
projectedTrainFaceMat = cvCreateMat(nTrainFaces,nEigens,CV_32FC1);
for(i = 0; i < nTrainFaces; i++)
{
    cvEigenDecomposite(
        faceImgArr[i],
        nEigens,
        eigenVectArr,
        0,NULL,
        pAvgTrainImg,
        projectedTrainFaceMat->data.fl + i*nEigens
        );
}
//store the recognition data as an .xml file
storeTrainingData();
}
int loadFaceImgArray( char* filename)
{
FILE* imgListFile = 0;
char imgFilename[512];
int iFace,nFaces = 0;
//Open the input file
imgListFile = fopen(filename,"r");
//count number of faces
while(fgets(imgFilename,512,imgListFile))
    ++nFaces;
rewind(imgListFile);
//allocate the face-image array and person number matrix
faceImgArr = (IplImage**)cvAlloc(nFaces*sizeof(IplImage*));
personNumTruthMat = cvCreateMat(1,nFaces,CV_32SC1);
//Store the face images in an array
for(iFace = 0; iFace < nFaces; iFace++)
{
    //read person number and name of image file
    fscanf(
        imgListFile,
        "%d %s",
        personNumTruthMat->data.i + iFace,
        imgFilename
            );
    //load the face image
    faceImgArr[iFace] = cvLoadImage(imgFilename,CV_LOAD_IMAGE_GRAYSCALE);
}
fclose(imgListFile);
return nFaces;
}
void doPCA()
{
int i;
CvTermCriteria calcLimit;
CvSize faceImgSize;
//set the number of eigenvalues to use
nEigens = nTrainFaces - 1;
//allocate the eigenvector images
//faceImgSize.width = faceImgArr[0]->width;
//faceImgSize.height = faceImgArr[0]->height;
faceImgSize.width = 170;
faceImgSize.height = 180;
eigenVectArr = (IplImage**)cvAlloc(nEigens*sizeof(IplImage));
for(i = 0; i < nEigens; i++)
    eigenVectArr[i] = cvCreateImage(faceImgSize,IPL_DEPTH_32F,1);
//allocate the eigenvalue array
eigenValMat = cvCreateMat(1,nEigens,CV_32FC1);
//allocate the averaged image
pAvgTrainImg = cvCreateImage(faceImgSize,IPL_DEPTH_32F,1);
//set the PCA termination criterion
calcLimit = cvTermCriteria(CV_TERMCRIT_ITER,nEigens,1);
//compute average image, eigenvalues, and eugenvectors
cvCalcEigenObjects(
    nTrainFaces,
    (void*)faceImgArr,
    (void*)eigenVectArr,
    CV_EIGOBJ_NO_CALLBACK,
    0,0,
    &calcLimit,
    pAvgTrainImg,
    eigenValMat->data.fl
    );
}
void storeTrainingData()
{
CvFileStorage* fileStorage;
int i;
//create a file-storage interface
fileStorage = cvOpenFileStorage("facedata.xml",0,CV_STORAGE_WRITE);
//store all the data
cvWriteInt(fileStorage,"nEigens",nEigens);
cvWriteInt(fileStorage,"nTrainFaces",nTrainFaces);
cvWrite(fileStorage,"trainPersonNumMat",personNumTruthMat,cvAttrList(0,0));
cvWrite(fileStorage,"eigenValMat",eigenValMat,cvAttrList(0,0));
cvWrite(fileStorage,"projectedTrainFaceMat",projectedTrainFaceMat,cvAttrList(0,0));
cvWrite(fileStorage,"avgTrainImg",pAvgTrainImg,cvAttrList(0,0));
for(i = 0; i < nEigens; i++)
{
    char varname[200];
    sprintf(varname,"eigenVect_%d",i);
    cvWrite(fileStorage,varname, eigenVectArr[i],cvAttrList(0,0));
}
//release the file-storage interface
cvReleaseFileStorage(&fileStorage);
}
void recognize(IplImage* TestImg)
{
CvMat* trainPersonNumMat = 0;
float* projectedTestFace = 0;
//load the saved training data
if(!loadTrainingData(&trainPersonNumMat))
    return;

projectedTestFace = (float*)cvAlloc(nEigens*sizeof(float));

int iNearest,nearest;
//project the test images onto the PCA subspace
cvEigenDecomposite(
    TestImg,
    nEigens,
    eigenVectArr,
    0,0,
    pAvgTrainImg,
    projectedTestFace
    );
iNearest = findNearestNeighbor(projectedTestFace);
nearest = trainPersonNumMat->data.i[iNearest ];
printf("nearest = %d",nearest);
}
int loadTrainingData(CvMat** pTrainPersonNumMat)
{
CvFileStorage* fileStorage;
int i;
//create a file-storage interface
fileStorage = cvOpenFileStorage("facedata.xml",0,CV_STORAGE_READ);
if(!fileStorage)
{
    fprintf(stderr,"Can't open facedata.xml \n");
    return 0;
}
nEigens = cvReadIntByName(fileStorage,0,"nEigens",0);
nTrainFaces = cvReadIntByName(fileStorage,0,"nTrainFaces",0);
*pTrainPersonNumMat = (CvMat*)cvReadByName(fileStorage,0,"trainPersonNumMat",0);
eigenValMat = (CvMat*)cvReadByName(fileStorage,0,"eigenValMat",0);
projectedTrainFaceMat = (CvMat*)cvReadByName(fileStorage,0,"projectedTrainFaceMat",0);
pAvgTrainImg = (IplImage*)cvReadByName(fileStorage,0,"avgTrainImg",0);
eigenVectArr = (IplImage**)cvAlloc(nTrainFaces*sizeof(IplImage*));
for(i = 0; i < nEigens; i++)
{
    char varname[200];
    sprintf(varname,"eigenVect_%d",i);
    eigenVectArr[i] = (IplImage*)cvReadByName(fileStorage,0,varname,0);
}
//release the file-storage interface
cvReleaseFileStorage(&fileStorage);
return 1;
}
int findNearestNeighbor(float* projectedTestFace)
{
double leastDistSq,distSq = 0;
int i,iTrain,iNearest = 0;
for(i = 0; i < nEigens; i++)
{
    float d_i = projectedTestFace[i] - projectedTrainFaceMat->data.fl[i];
    distSq +=d_i*d_i;
}
leastDistSq = distSq;
iNearest = 0;
for(iTrain = 1;iTrain < nTrainFaces; iTrain++ )
{
    distSq = 0;
    for(i = 0; i < nEigens; i++)
    {
        float d_i = projectedTestFace[i] -     projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
        distSq +=d_i*d_i;
    }
    if(distSq < leastDistSq)
    {
        leastDistSq = distSq;
        iNearest = iTrain;
    }
}
return iNearest;
}
/*************************************************/
//Main function
int main()
{

learn();
//IplImage* test_img = cvLoadImage("D:\document\Study\university of technology\semester_8\Computer Vision\Pics for test\faces\face1.bmp");
//recognize(test_img);
return 0;
}

When debugging, there's an error at function cvCalcEigenObjects as follow:

OpenCV error: Bad argument <unrecognized or="" unsupported="" array="" type=""> in unknown function, file ......\src\opencv\modules\core\src\array.cpp, line 1070

How can I fix this error ? hope for help! I've done many searches on internet but there's no effective solution.


here is the output of compiler! enter image description here