Hi guys, I'm currently trying to produce a facial detection application, but I seem to have some problems. My program, is able to recognise multiple users, and match their captured image to one saved in the database. However, if a person who has not registered is photographed, it is supposed open a pop-up of a picture of my choosing (in the code below I've chosen a picture of Mario) and tell the user that he/she is not in the database. The code for the condition of both recognizing and showing an unrecognised user is below.

The problem I have, is that when an unrecognised user is captured, it will still show user 1 or 2, instead of a "Mario" image. I'm unsure if it is the recognition algorithm (code also below) or my "if" statement that is at fault. I'm now trying with only 2 users to minimize the chance of errors. Can anyone help?

void CzebraDlg::OnBnClickedCapturetrain()
{
else if( LearnOrRecognize == 2)  // CASE 2 (CAPTURE FOR RECOGNIZE)
{
    sprintf(PicFname, "%s", "test.jpg");
    sprintf(TestFname, "%s", "test.txt");

    ofstream outfile;   //An object:myfile of type "ofstream" is created to allow the file to be opened for writing
    outfile.open(TestFname, ios::app);

    char *temp  = new char[50];

    sprintf(temp, "%s", "1 test.jpg");
    outfile << temp <<endl;

    cvSaveImage(PicFname, gregion);

    recognize();

    IplImage* Identified_Person_Img;

    if (RESULT_NEAREST == 1) //Nearest refers to ID of person being recognized
    {
        cvNamedWindow( "ID01", 0 );
        cvResizeWindow( "ID01", 160, 160 );
        cvMoveWindow( "ID01", 673, 506 );
        Identified_Person_Img = cvLoadImage( "D:\\FYP\\01\\1.jpg", 1 );
        cvShowImage("ID01", Identified_Person_Img);
        EEE(node_number=0); //meant for hardware interfacing, not used
    }
    if (RESULT_NEAREST !=1)
    {
        if (RESULT_NEAREST == 2)
        {
            cvNamedWindow( "ID02", 0 );
            cvResizeWindow( "ID02", 160, 160 );
            cvMoveWindow( "ID02", 673, 506 );
            Identified_Person_Img = cvLoadImage( "D:\\FYP\\02\\1.jpg", 1 );
            cvShowImage("ID02", Identified_Person_Img);
            EEE(node_number=1);
        }
    }
    if (!(RESULT_NEAREST == 1) && !(RESULT_NEAREST == 2))
    {
        cvNamedWindow( "Unknown Face Detected", 0 );
        cvResizeWindow( "Unknown Face Detected", 160, 160 );
        cvMoveWindow( "Unknown Face Detected", 673, 506 );
        IplImage* UnknownFace;
        UnknownFace = cvLoadImage( "D:\\FYP\\MARIO1.jpg", 1 );
        IplImage *FUnknownFace = 0;
        FUnknownFace = cvCreateImage(cvSize(160, 160),            
            UnknownFace->depth, UnknownFace->nChannels);
        cvResize( UnknownFace, FUnknownFace, CV_INTER_LINEAR );
        cvShowImage("Unknown Face Detected", FUnknownFace);
        EEE(node_number=20);
    }
    outfile.close();
}
}

Recognition function is below for reference and error checking.

void recognize()
{
	int i, nTestFaces  = 0;         // the number of test images
	CvMat * trainPersonNumMat = 0;  // the person numbers during training
	float * projectedTestFace = 0;

	// load test images and ground truth for person number
	nTestFaces = loadFaceImgArray("test.txt");

	// load the saved training data
	if( !loadTrainingData( &trainPersonNumMat ) ) return;

	// project the test images onto the PCA subspace
	projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) );

	int iNearest, nearest, truth;

	for(i=0; i<nTestFaces; i++)
	{
		// project the test image onto the PCA subspace
		cvEigenDecomposite
			(
				faceImgArr[i],
				nEigens,
				eigenVectArr,
				0, 0,
				pAvgTrainImg,
				projectedTestFace);

		iNearest = findNearestNeighbor(projectedTestFace);
		truth    = personNumTruthMat->data.i[i];
		nearest  = trainPersonNumMat->data.i[iNearest];
		
		}
        RESULT_NEAREST = nearest;
		RESULT_TRUTH   = truth;
}

Function that gives values to the one above's code is below

int findNearestNeighbor(float * projectedTestFace)
{
	double leastDistSq = DBL_MAX;
	int i, iTrain, iNearest = 0;

	for(iTrain=0; iTrain<nTrainFaces; iTrain++)
	{
		double distSq=0;

		for(i=0; i<nEigens; i++)
		{
			float d_i =
				projectedTestFace[i] -
				projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
			distSq += d_i*d_i / eigenValMat->data.fl[i];
			
		}

		if(distSq < leastDistSq)
		{
			leastDistSq = distSq;
			iNearest = iTrain;
		}
	}

	return iNearest;
}

I'm using MFC for the GUI creation, but I don't think that should be a problem as of now. Thanks a lot for any help in advance. If you need to see the entire .cpp file that these snippets came from, I have attached it as well.

1. Don't fall in the magic pushButton mistake, try to separate gui and behavior.

2. How is RESULT_NEAREST variable declared ?

3. have you tried to debug, or just print out the value of RESULT_NEAREST after you compute it, let's say line 19 in your first file ?

Hello there, I tried debugging the values of "RESULT_NEAREST". The values are correct when different users that are already registered inside are captured, but I just noticed, that it always gives itself a value of "1" when an unrecognized person is captured, causing the problem. Is there a fix for this? Thanks for the reply.

This variable is declared in a another header file with it's function prototype. This header is included in the .cpp file I uploaded (declaration from header file below).

void recognize();
int RESULT_NEAREST = 0;

Sure, there is also a variable called RESULT_TRUTH. I don't know how it is filled, but maybe you could check the value of this variable to know if the detection was successful or not...

Hi, I just had a discussion with my boss. Apparently the algorithm may have some accuracy problems, so we will just wait that part out with the higher-ups. Now though I'm trying make the code more optimized and easier to read but I seem to have a small problem.

I'm trying to replace this entire section (below)

if (RESULT_NEAREST == 1) //Nearest refers to ID of person being recognized
    {
        cvNamedWindow( "ID01", 0 );
        cvResizeWindow( "ID01", 160, 160 );
        cvMoveWindow( "ID01", 673, 506 );
        Identified_Person_Img = cvLoadImage( "D:\\FYP\\01\\1.jpg", 1 );
        cvShowImage("ID01", Identified_Person_Img);
        EEE(node_number=0); //meant for hardware interfacing, not used
    }
    if (RESULT_NEAREST !=1)
    {
        if (RESULT_NEAREST == 2)
        {
            cvNamedWindow( "ID02", 0 );
            cvResizeWindow( "ID02", 160, 160 );
            cvMoveWindow( "ID02", 673, 506 );
            Identified_Person_Img = cvLoadImage( "D:\\FYP\\02\\1.jpg", 1 );
            cvShowImage("ID02", Identified_Person_Img);
            EEE(node_number=1);
        }
    }
    if (!(RESULT_NEAREST == 1) && !(RESULT_NEAREST == 2))
    {
        cvNamedWindow( "Unknown Face Detected", 0 );
        cvResizeWindow( "Unknown Face Detected", 160, 160 );
        cvMoveWindow( "Unknown Face Detected", 673, 506 );
        IplImage* UnknownFace;
        UnknownFace = cvLoadImage( "D:\\FYP\\MARIO1.jpg", 1 );
        IplImage *FUnknownFace = 0;
        FUnknownFace = cvCreateImage(cvSize(160, 160),            
            UnknownFace->depth, UnknownFace->nChannels);
        cvResize( UnknownFace, FUnknownFace, CV_INTER_LINEAR );
        cvShowImage("Unknown Face Detected", FUnknownFace);
        EEE(node_number=20);
    }

With this

char buffer[50];
	int n;
	n = sprintf (buffer,"D:\\FYP\\0%d\\1.jpg", RESULT_NEAREST);
		cvNamedWindow( "ID", 0 );
		cvResizeWindow( "ID", 160, 160 );
		cvMoveWindow( "ID", 673, 506 );
		Identified_Person_Img = cvLoadImage( n, 1 ); //Actual file directory is "D:/FYP/<ID number, eg. 01,02,etc>/1.jpg
		cvShowImage("ID", Identified_Person_Img);
		EEE(node_number=ID);

if (RESULT_NEAREST !=1 && RESULT_NEAREST !=2)
		{
		cvNamedWindow( "Unknown Face Detected", 0 );
		cvResizeWindow( "Unknown Face Detected", 160, 160 );
		cvMoveWindow( "Unknown Face Detected", 673, 506 );
		IplImage* UnknownFace;
		UnknownFace = cvLoadImage( "D:\\FYP\\MARIO1.jpg", 1 );
		IplImage *FUnknownFace = 0;
	              FUnknownFace = cvCreateImage(cvSize(160, 160),            
								UnknownFace->depth, UnknownFace->nChannels);
				  cvResize( UnknownFace, FUnknownFace, CV_INTER_LINEAR );
		cvShowImage("Unknown Face Detected", FUnknownFace);
		EEE(node_number=20);
		}

But I seem to get a "error C2664: 'cvLoadImage' : cannot convert parameter 1 from 'int' to 'const char *'" problem. I've tried changing the variable types when I declared them (below) but with no effect. Using the debugger, my values when I click the button are correct so I think it is a problem is in my syntax with how I called the pop-up and the file directory. Is there a way to fix it? Thanks a lot in advance.

*note, these 2 are declared in a separate header file but I don't think it should matter.

int ID=0;
int RESULT_NEAREST = 0;

Loading the face image

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);

		if( !faceImgArr[iFace] )
		{
			/*fprintf(stderr, "Can\'t load image from %s\n", imgFilename);*/
			return 0;
		}
	}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.