cvCalcEigenObjects in opencv?

asked 2013-04-29 05:50:32 -0600

nqchanh gravatar image

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 ...
(more)
edit retag flag offensive close merge delete

Comments

i think the problem here is the function "cvCalcEigenObjects", but i don't know what wrong with it ?

nqchanh gravatar imagenqchanh ( 2013-04-29 05:51:58 -0600 )edit

Your image is covering the exact location where your function pointer stands (green arrow). Could you check the exact code on the previous line and post this? It will help us debug the problem.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-04-29 07:20:56 -0600 )edit

sorry, but what u mean, Steven Puttemans? i've posted the full code! could u tell me more clearly what u need ? ^~^

nqchanh gravatar imagenqchanh ( 2013-04-29 19:57:53 -0600 )edit

look at your image, there was a green arrow (the program counter) that iterates through your code. Please look up after which line of code, the error occurs.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-04-30 01:35:50 -0600 )edit