Eye Detection Using Open CV(Should be run on a system with Open CV library)

Dependencies:   mbed

main.cpp

Committer:
pramodnataraja
Date:
2011-12-14
Revision:
0:728af114b613

File content as of revision 0:728af114b613:

/* This code should be compiled on a system with Open CV library installed and run from Visual Studio if running from Windows platform*/

#include "stdafx.h"
#include "cv.h" 
#include "highgui.h"

#include <iostream>
#include <conio.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <windows.h>


using namespace std;
using namespace cv;

#define SCALE 1

#define SCALING_FACTOR_FACE			1.1
#define MIN_SIZE_FACE				30
#define FLAGS_FACE					CV_HAAR_FIND_BIGGEST_OBJECT
#define COLOR_FACE					CV_RGB(255, 0, 0)
#define FEATURE_FACE				"C:/OpenCV2.0/data/haarcascades/haarcascade_frontalface_alt.xml" //You need to put the correct path to your templates

#define EYE
#define SCALING_FACTOR_EYE			1.1
#define MIN_SIZE_EYE				20
#define FLAGS_EYE					CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_DO_ROUGH_SEARCH | CV_HAAR_SCALE_IMAGE | CV_HAAR_DO_CANNY_PRUNING
#define COLOR_EYE					CV_RGB(0, 255, 0)
#define FEATURE_EYE					"C:/OpenCV2.0/data/haarcascades/haarcascade_mcs_eyepair_small.xml"

//#define NOSE
#define SCALING_FACTOR_NOSE			1.1
#define MIN_SIZE_NOSE				20
#define FLAGS_NOSE					CV_HAAR_DO_CANNY_PRUNING
#define COLOR_NOSE					CV_RGB(0, 0, 255)
#define FEATURE_NOSE				"C:/OpenCV2.0/data/haarcascades/haarcascade_mcs_nose.xml"

#define THRESHOLD_X					10
#define THRESHOLD_Y					13

#define DISCARD_VALUE				10

#define strlen(cBufferOut)			1

int detect_faces(Mat& img);

CascadeClassifier cascade;
CascadeClassifier cascade_eye;
CascadeClassifier cascade_nose;
CvMemStorage* storage = (CvMemStorage*)NULL;

int disp_x = 0;
int disp_y = 0;
int prev_disp_x = 0;
int prev_disp_y = 0;
int prev_pos_x = 0;
int prev_pos_y = 0;
int cur_pos_x = 0;
int cur_pos_y = 0;

HANDLE hSerial;
DCB dcb;

// A Simple Camera Capture Framework 
int main()
{
/******************************************************* SETUP SERIAL COM PORT *********************************************/
	DWORD cBytesOut, cBytesIn;
	DWORD dwMask;

	char* cBufferOut;
	char front = '1';//"front";
	char back = '2';//"back";
	char left = '3';//"left";
	char right = '4';//"right";
	char half_front_right = '5';//"half_front_right";
	char half_front_left = '6';//"half_front_left";
	char half_back_right = '7';//"half_back_right";
	char half_back_left = '8';//"half_back_left";
	char onOff = '0';//"onOff";

	int valid = 0;
	int discard = 0;
	int firstValue = 1;

	hSerial = CreateFile(_T("COM2"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

	if(hSerial == INVALID_HANDLE_VALUE)
	{
		printf("Failure\n");
		printf("%d\n",hSerial);
		printf("%d\n",GetLastError());
	}

	GetCommState(hSerial, &dcb);
	dcb.BaudRate = 9600;
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;
	SetCommState(hSerial, &dcb);
/*************************************************************************************************************/

	double t;

	CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );

	if ( !capture )
	{
	 fprintf( stderr, "ERROR: capture is NULL \n" );
	 getchar();
	 return -1;
	}

	// Create a window in which the captured images will be presented
	cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );

	// Show the image captured from the camera in the window and repeat
	while ( 1 )
	{
	 // Get one frame
	 IplImage* iplImg = cvQueryFrame( capture );
	 Mat frame, frameCopy;

        frame = iplImg;
        if( frame.empty() )
            break;
        if( iplImg->origin == IPL_ORIGIN_TL )
            frame.copyTo( frameCopy );
        else
            flip( frame, frameCopy, 0 );

	if (frameCopy.empty())
	 {
	   fprintf( stderr, "ERROR: frame is null...\n" );
	   getchar();
	   break;
	 }
	
	if(discard <= 0)
	{
		 prev_pos_x = cur_pos_x;
		 prev_pos_y = cur_pos_y;

		 prev_disp_x = disp_x;
		 prev_disp_y = disp_y;

		 t = (double)cvGetTickCount();
		 detect_faces(frameCopy);
		 t = (double)cvGetTickCount() - t;
		 
		disp_x = cur_pos_x - prev_pos_x;
		disp_y = cur_pos_y - prev_pos_y;

		if(((disp_x < THRESHOLD_X) && (disp_x > (-1 * THRESHOLD_X))) || (firstValue == 1))
			 disp_x = 0;

		 if(((disp_y < THRESHOLD_Y) && (disp_y > (-1 * THRESHOLD_Y))) || (firstValue == 1))
			 disp_y = 0;

		 if(firstValue == 1)
			 firstValue = 0;

	/*	 if((disp_x != 0) && (prev_disp_x == 0))
		 {
			 printf("disp_x = %d\n", disp_x);
		 }
		 if((disp_y != 0) && (prev_disp_y == 0))
		 {
			 printf("\tdisp_y = %d\n", disp_y);
		 }*/

		valid = 1;

		 if((disp_x == 0) && (disp_y < 0) && (prev_disp_y == 0))
		 {
			 printf("front");
			 cBufferOut = &front;
		 }
		 else if((disp_x == 0) && (disp_y > 0) && (prev_disp_y == 0))
		 {
			 printf("back");
			 cBufferOut = &back;
		 }
		 else if((disp_x < 0) && (disp_y == 0) && (prev_disp_x == 0))
		 {
			 printf("right");
			 cBufferOut = &right;
		 }
		 else if((disp_x > 0) && (disp_y == 0) && (prev_disp_x == 0))
		 {
			 printf("left");
			 cBufferOut = &left;
		 }
		 else if((disp_x < 0) && (prev_disp_x == 0) && (disp_y < 0) && (prev_disp_y == 0))
		 {
			 printf("half_front_right");
			 cBufferOut = &half_front_right;
		 }
		 else if((disp_x > 0) && (prev_disp_x == 0) && (disp_y < 0) && (prev_disp_y == 0))
		 {
			 printf("half_front_left");
			 cBufferOut = &half_front_left;
		 }
		 else if((disp_x < 0) && (prev_disp_x == 0) && (disp_y > 0) && (prev_disp_y == 0))
		 {
			 printf("half_back_right");
			 cBufferOut = &half_back_right;
		 }
		 else if((disp_x > 0) && (prev_disp_x == 0) && (disp_y > 0) && (prev_disp_y == 0))
		 {
			 printf("half_back_left");
			 cBufferOut = &half_back_left;
		 }
		 else
		 {
			 valid = 0;
		 }

		 if(valid != 0)
		 {
			 printf("\n");
			 //printf("output = %c \n",*cBufferOut);

			 if(!WriteFile(hSerial, cBufferOut, 1, &cBytesOut, NULL))
			{
				printf("File write error\n");
			}

			 discard = DISCARD_VALUE;
		 }
	}
	else
	{
		detect_faces(frameCopy);
		discard--;
	}

	if((cvWaitKey(10) & 255) == 32)
	 {
		 printf("onoff\n");
		 cBufferOut = &onOff;

	 	if(!WriteFile(hSerial, cBufferOut, 1, &cBytesOut, NULL))
		{
			printf("File write error.........\n");
		}
	 }

	 //imshow( "mywindow", frame );

	 // Do not release the frame!
	 //If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
	 //remove higher bits using AND operator
	 if ( (cvWaitKey(10) & 255) == 27 ) break;

	 
	}
	// Release the capture device housekeeping
	cvReleaseCapture( &capture );
	cvDestroyWindow( "mywindow" );

	CloseHandle(hSerial);

	return 0;
}



int detect_faces(Mat& img)
{
  Mat gray, img2;
  Mat smallImg( cvRound (img.rows/SCALE), cvRound(img.cols/SCALE), CV_8UC1 );

	cvtColor( img, gray, CV_BGR2GRAY );
	resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
	equalizeHist( smallImg, smallImg );

#pragma region FEATURE FILES
  /* Load the face detector and create memory storage
    `cascade` and `storage` are global variables */
  if (cascade.empty())
  {
    char* file = FEATURE_FACE; //haarcascade_eye_tree_eyeglasses.xml";


	if(!cascade.load(file))
	{
		fprintf( stderr, "ERROR: Invalid cascade path...\n" );
	   getchar();
	   return 0;
	}

    storage = cvCreateMemStorage(0);
  }

  if (cascade_nose.empty())
  {
	  char* file = FEATURE_NOSE; //haarcascade_eye_tree_eyeglasses.xml";

	if(!cascade_nose.load(file))
	{
		fprintf( stderr, "ERROR: Invalid cascade path...\n" );
	   getchar();
	   return 0;
	}
  }

  if (cascade_eye.empty())
  {
    char* file = FEATURE_EYE;//haarcascade_eye_tree_eyeglasses.xml";

	if(!cascade_eye.load(file))
	{
		fprintf( stderr, "ERROR: Invalid cascade path...\n" );
	   getchar();
	   return 0;
	}
  }
#pragma endregion

  vector<Rect> faces;

  cascade.detectMultiScale(smallImg, faces, SCALING_FACTOR_FACE, 2, FLAGS_FACE, Size(MIN_SIZE_FACE, MIN_SIZE_FACE) );

  for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++)
  {
	  img2 = smallImg(*r);

		vector<Rect> eyes;
		vector<Rect> nose;

#ifdef EYE
		cascade_eye.detectMultiScale(img2, eyes, SCALING_FACTOR_EYE, 2, FLAGS_EYE, Size(MIN_SIZE_EYE, MIN_SIZE_EYE) );
		
		for( vector<Rect>::const_iterator nr = eyes.begin(); nr != eyes.end(); nr++ )
        {
			rectangle(smallImg, cvPoint(r->x + nr->x, r->y + nr->y), cvPoint(r->x + nr->x + nr->width, r->y + nr->y + nr->height), COLOR_EYE, 1, 8, 0);
			cur_pos_x = r->x + nr->x + (nr->width / 2);
			cur_pos_y = r->y + nr->y + (nr->height / 2);
		}
#endif


#ifdef NOSE
		cascade_nose.detectMultiScale(img2, nose, SCALING_FACTOR_NOSE, 2, FLAGS_NOSE, Size(MIN_SIZE_NOSE, MIN_SIZE_NOSE) );

		for( vector<Rect>::const_iterator nr = nose.begin(); nr != nose.end(); nr++ )
		//vector<Rect>::const_iterator nr = nose.end() - 1;
        {
			rectangle(smallImg, cvPoint(r->x + nr->x, r->y + nr->y), cvPoint(r->x + nr->x + nr->width, r->y + nr->y + nr->height), COLOR_NOSE, 1, 8, 0);
			cur_pos_x = r->x + nr->x + (nr->width / 2);
			cur_pos_y = r->y + nr->y + (nr->height / 2);
		}
#endif

		//if((int)eyes.size() >= 2)
		{
			rectangle(smallImg, cvPoint(r->x, r->y), cvPoint(r->x + r->width, r->y + r->height), COLOR_FACE, 1, 8, 0);
		}
  }

  imshow("mywindow",smallImg);

  return 0; //(int)faces.size();
}