CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Jun 2010
    Posts
    10

    Face detection program bug

    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?

    Code:
    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.

    Code:
    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

    Code:
    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 code that these snippets are taken from, I have attached it (zebraDlg.cpp).
    Attached Files Attached Files
    Last edited by meepokman; June 17th, 2010 at 07:48 PM.

  2. #2
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Face detection program bug

    First use code tags.

    I don't know what the problem is, but your use of if statements is a little odd.

    Code:
    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);
        }
    }
    What purpose does the first if serve there? If it's equal to 2, obviously it's not equal to 1.

    Code:
    if (!(RESULT_NEAREST == 1) && !(RESULT_NEAREST == 2))
    What's wrong with
    Code:
    if (RESULT_NEAREST != 1 && RESULT_NEAREST != 2)
    That's easier to read to me.
    Even better would be to use else statements
    Code:
    if (RESULT_NEAREST == 1)
    {
    }
    else
    if (RESULT_NEAREST == 2)
    {
    }
    else
    {
    }

  3. #3
    Join Date
    Jun 2010
    Posts
    10

    Re: Face detection program bug

    Hello there, I've tidied the codes up like you suggested (posted below). I also just noticed that within the "recognize" function, the 'for' loop to that examines the test image will keep going as far as the number of images in the database, instead of exiting. Could this be a problem?

    I added a 'break' after assignment to "RESULT_NEAREST" but it did not seem to help. Is there any possible solution to this?

    Code:
    void recognize() //full function posted at first post
    {
    .....
    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];
    		break; //just added in
    		}
    				
                    RESULT_NEAREST = nearest;
    		RESULT_TRUTH   = truth;

    Tidied up sections
    Code:
    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);  //for hardware interfacing, ignore for now
    		}
    	else if (RESULT_NEAREST == 2) //I have left this in as I will be increasing the number of users
    		{
    		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);
    		}
        else
    		{
    		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);
    		}

  4. #4
    Join Date
    Jun 2010
    Posts
    10

    Re: Face detection program bug

    Sorry the the double post, but I cannot edit my post, so I've reposted the full "recognize" function below with proper code tags. If any admin can help, could my earlier post be edited by you to add in the code tags? Apologies for any inconvenience caused.

    Code:
     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;
    }

  5. #5
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Face detection program bug

    This is a problem for the debugger to solve. Have you tried stepping through the code?

  6. #6
    Join Date
    Jun 2010
    Posts
    10

    Re: Face detection program bug

    Quote Originally Posted by GCDEF View Post
    This is a problem for the debugger to solve. Have you tried stepping through the code?
    Hi, 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.

  7. #7
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Face detection program bug

    Quote Originally Posted by meepokman View Post
    Hi, 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.
    You need to step through the code and find out where it's going wrong. And please properly indent your code. It's very hard to read like that.

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Face detection program bug

    Quote Originally Posted by meepokman View Post
    Hi guys, I'm currently trying to produce a facial detection application, but I seem to have some problems.
    Why do you repeatedly do this?
    Code:
    char *temp  = new char[50];
    First, your code has a memory leak, since you never deallocated the memory with delete[]

    Second, there is no need to allocate memory. The array is set to 50 characters, so why didn't you just declare an array of 50 chars?
    Code:
    char temp[50];  // this is all you need to do
    Your code unnecessarily calls new[], slowing down your program, and if you call that routine many times, your application is also eating up the free-store memory.

    Third, what if whatever you're putting into this array has more than 50 characters? Where is the check for exceeding the 50 character (49 if it's null terminated) limit?

    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Face detection program bug

    In addition, you have repeated code. That entire block of "if( strcmp(Person", stuff in OnBnClickedCapturetrain() can be written like this:
    Code:
    if( LearnOrRecognize == 1)   // CASE 1 (CAPTURE FOR LEARN)
    {
    //...
         ID = atoi(Person);
         UpdateData();
         csSaveImage(PicFname, gregion);
         char temp[50];
         sprintf(temp, "D:/FYP/&#37;s/%d%s", Person, m_count, ".jpg");
         myfile <<ID<<" "<< temp <<endl;
    //...
    }
    The only difference is the ID number and the Person number.

    A sign of a good programmer is one that sees obvious repeated code, and doesn't write repeated code. When you realize you're writing the same thing over and over again 20+ times, with hardly any difference in what you're writing, then you should realize that you're doing something inefficiently or unnecessarily.

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Jun 2010
    Posts
    10

    Re: Face detection program bug

    Hello Paul, thanks a lot for your suggestions. I've implemented and modified them accordingly. Following what you said, I'm trying to simplify the code so it is easier to read before I try to solve any more problems. For the "recognize" function, I'm trying to do what you did but I seem to have some difficulties. When I try to recognize the image with the code below, it returns a blank pop-up. Using the debugger, my values when I click the button are correct so I think it is a problem with how I called the pop-up and the file directory. Is there any error?

    Code:
    sprintf(temp, "%s", RESULT_NEAREST); //not really sure if this is correct, best I could find
    		cvNamedWindow( "ID", 0 );
    		cvResizeWindow( "ID", 160, 160 );
    		cvMoveWindow( "ID", 673, 506 );
    		Identified_Person_Img = cvLoadImage( "D:/FYP/0%s/1.jpg", 1 ); //actual directory is "D:/FYP/<ID of user, eg. 01,02,etc>/1.jpg"
    		cvShowImage("ID", Identified_Person_Img);

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured