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

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
pramodnataraja
Date:
Wed Dec 14 04:51:31 2011 +0000
Commit message:
Version 1.0

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Dec 14 04:51:31 2011 +0000
@@ -0,0 +1,367 @@
+/* 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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Dec 14 04:51:31 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/078e4b97a13e