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

Dependencies:   mbed

Revision:
0:728af114b613
--- /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();
+}