Eye Blink detection OpenCV C++

asked 2015-09-16 04:28:58 -0500

HosseinH gravatar image

I am trying to write an Blink detection but it does not work properly. It finds the face and eyes properly.then i trying to find a circle in the eye area (Pupil) but it is not always found and when it is found it detects blink although there is no(the counter then goes ever higher). I have tried different methods and filter (HoughCircles, Canny,threshold, medianBlur, smooth) but it does not change. I hope someone can help me and sorry for my bad English. Here is my code:

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <vector>
#include <math.h>
#include <iomanip>
#include <sstream>
#include <string>

#include <opencv2\objdetect\objdetect.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>#include <opencv2\video\tracking.hpp>
#include "opencv2/opencv.hpp"

// Include OpenCV's C++ Interface
#include "opencv2/opencv.hpp"


const float eyeTop = 0.26f;     //y
const float eyeSide = 0.16f;  //x
const float eyeHeight = 0.28f;  //h
const float eyeWidth = 0.65f;       //w
const int calibrationDefault = 100;

int blinknumber =0;
int calibrationFace = calibrationDefault;


bool leftEyeOpen = true;
bool rightEyeOpen = true;

using namespace cv;
using namespace std;

const std::string casceye_name = "C:\\Users\\Hossein Hezarpisheh\\Documents\\Visual Studio 2010\\Projects\\projek1\\haarcascade_mcs_eyepair_big.xml";
const std::string face_cascade_name = "C:\\Users\\Hossein Hezarpisheh\\Documents\\Visual Studio 2010\\Projects\\projek1\\haarcascade_frontalface_alt.xml";

Mat lastFace;
Mat actualFace;

void headTracing(Mat grayImage, Mat image, CascadeClassifier casceye, CascadeClassifier cascFace, Rect &faceArea);
Rect detectLargestObject(Mat grayImage, CascadeClassifier cascFace);
void eyeTracking(Mat &actualFace, Mat &lastFace,int &blinknumber);
void getEyes(Mat &face, Mat &eye);

namespace patch
{
template < typename T > string to_string(T n )
{
ostringstream stm ;
stm << n ;
return stm.str() ;
}
}





// main   

int main()
{
 Rect faceArea; 
 CascadeClassifier cascFace, casceye;

if (!cascFace.load(face_cascade_name)){ printf("--(!)Error loading face cascade\n"); return -1; };
if (!casceye.load(casceye_name)){ printf("--(!)Error loading eyes cascade\n"); return -1; };


cout << "\n\tESC - Programm beenden\n\tc - zaehler auf 0 setzen\n\n";

namedWindow("Blinzel Erkennung", CV_WINDOW_AUTOSIZE);

VideoCapture capture(0);
if (!capture.isOpened())
{
cout<<"Kamera wurde nicht gefunden!"<<endl;
return 1;
}

Mat Image;

while (1)
{
    Mat GrayImage;
    capture >> Image;

    if (Image.empty()){                                         
    continue;
    }

    flip(Image, Image, 1);                                  
    cvtColor(Image, GrayImage, CV_BGR2GRAY);

headTracing(GrayImage, Image, casceye , cascFace, faceArea);        


switch (waitKey(2)) {
case 27:
 return 0;                                                              
    break;
case120:                                                                        
    calibrationFace = 0;
    break;


    case 99:                                                                        // c key - zähler auf 0 setzen
    leftEyeOpen = true;
    rightEyeOpen = true;
    blinkNumberLeft = 0;
    blinkNumberRight = 0;
    break;
    }
}
return 0;
}




void calcFlow(const Mat& flow, Mat& cflowmap, int step, int &globalMoveX, int &globalMoveY)
{
int localMoveX = 0;
int localMoveY = 0;

for (int y = 0; y < cflowmap.rows; y += step)
{
for (int x = 0; x < cflowmap.cols; x += step)
{
    const Point2f& fxy = flow.at<Point2f>(y, x);

    localMoveX = localMoveX + fxy.x;
    localMoveY = localMoveY + fxy.y;
    }
    }

globalMoveX = (localMoveX / (cflowmap.cols * cflowmap.rows))*2;                         
globalMoveY = (localMoveY / (cflowmap.rows * cflowmap.cols))*2;
}


void headTracing(Mat grayImage, Mat image, CascadeClassifier casceye, CascadeClassifier cascFace, Rect &faceArea) {

Rect face = detectLargestObject(grayImage, cascFace);
if (face.width == 0 && face.height == 0) {
imshow("Ergebnis", image);                                  
return;                                                             
}

calibrationFace = calibrationFace - 1;

if (faceArea.height == 0|| calibrationFace < 1) {           
faceArea = face;
lastFace = grayImage ...
(more)
edit retag flag offensive close merge delete

Comments

What is the resolution of your detected eye ? I do not thin that this approach is going to work in a small image, or that has variations in illumination. A better approach should be a classifier of the eyes (closed/opened) and there you will need some eye-databases. More there would be a problem when there is make-up. And if you do not detect always the eyes, then you may get in the case of eyebrow and then what? I would suggest you the landmarks approach, based on ch6

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-09-16 06:54:43 -0500 )edit

i have already trained a classifier but i dont know how i can use it in my code to detect close/open eyes. My problem is where i have to put the blinkNumber for counting the blink.

HosseinH gravatar imageHosseinH ( 2015-09-17 02:25:25 -0500 )edit

You should have something like this Mat eye=face(eyeDetection); resize(eye, eye, trainedSize); classifier.predict(eye);. Or you can use descriptors (Dense detection + some descriptor) for better results, but you need to train the classifier on the used descriptors.

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-09-17 02:59:37 -0500 )edit