track_eye.cpp ( File view )

• By marque 2014-03-29
• View(s)：51
• Point(s)： 2
```			#include <iostream>

#include "constants.h"
#include "track_eye.h"

// Histogram Equalize seperately for the left and right sides of the face.
void equalizeLeftAndRightHalves(cv::Mat &faceImg)
{

// It is common that there is stronger light from one half of the face than the other. In that case,
// if you simply did histogram equalization on the whole face then it would make one half dark and
// one half bright. So we will do histogram equalization separately on each face half, so they will
// both look similar on average. But this would cause a sharp edge in the middle of the face, because
// the left half and right half would be suddenly different. So we also histogram equalize the whole
// image, and in the middle part we blend the 3 images together for a smooth brightness transition.

int w = faceImg.cols;
int h = faceImg.rows;

// 1) First, equalize the whole face.
cv::Mat wholeFace;
equalizeHist(faceImg, wholeFace);

// 2) Equalize the left half and the right half of the face separately.
int midX = w/2;
cv::Mat leftSide = faceImg(cv::Rect(0,0, midX,h));
cv::Mat rightSide = faceImg(cv::Rect(midX,0, w-midX,h));
equalizeHist(leftSide, leftSide);
equalizeHist(rightSide, rightSide);

// 3) Combine the left half and right half and whole face together, so that it has a smooth transition.
for (int y=0; y<h; y++) {

for (int x=0; x<w; x++) {

int v;
if (x < w/4) {
// Left 25%: just use the left face.
v = leftSide.at<uchar>(y,x);

}
else if (x < w*2/4) {
// Mid-left 25%: blend the left face & whole face.
int lv = leftSide.at<uchar>(y,x);
int wv = wholeFace.at<uchar>(y,x);
// Blend more of the whole face as it moves further right along the face.
float f = (x - w*1/4) / (float)(w*0.25f);
v = cvRound((1.0f - f) * lv + (f) * wv);

}
else if (x < w*3/4) {
// Mid-right 25%: blend the right face & whole face.
int rv = rightSide.at<uchar>(y,x-midX);
int wv = wholeFace.at<uchar>(y,x);
// Blend more of the right-side face as it moves further right along the face.
float f = (x - w*2/4) / (float)(w*0.25f);
v = cvRound((1.0f - f) * wv + (f) * rv);

}
else {
// Right 25%: just use the right face.
v = rightSide.at<uchar>(y,x-midX);

}
faceImg.at<uchar>(y,x) = v;

}// end x loop

}//end y loop

}

static bool getIrisArea(cv::Mat faceROI, cv::Rect eyeRegion, cv::Rect& maxContourRect)
{

// equalize light effect
//equalizeLeftAndRightHalves(faceROI);
cv::Mat eyeROI = faceROI(eyeRegion);
cv::Mat eyeBinInv;

double minVal = 0;
minMaxLoc(eyeROI, &minVal, NULL, NULL, NULL);

threshold(eyeROI, eyeBinInv, minVal + 10, 255, cv::THRESH_BINARY_INV);

//(Optional) remove noise (small areas of white pixels)
// cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3), cv::Point(1, 1));
// erode(eyeBinInv, eyeBinInv, element);
// dilate(eyeBinInv, eyeBinInv, element);

std::vector<cv::Vec4i> hierarchy;
std::vector< std::vector <cv::Point2i> > contours;

findContours(eyeBinInv, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

//find contour with max area
int maxArea = 0;

for (unsigned int i=0; i<contours.size(); i++)
{

int area = contourArea(contours[i]);
cv::Rect rect = boundingRect(contours[i]);
double squareKoef = ((double) rect.width)/rect.height;

//check if contour is like square (shape)
#define SQUARE_KOEF 1.5
if (area>maxArea && squareKoef < SQUARE_KOEF && squareKoef > 1.0/SQUARE_KOEF)
{

maxArea = area;
maxContourRect = rect;

}

}
// std::cout << "Max Area" << maxArea << std::endl;
return (maxArea > min_iris_area);

}

void trackEyes(cv::Mat frame_gray, cv::Rect face, cv::Point& rightPupil, cv::Point& leftPupil )
{

cv::Mat faceROI = frame_gray(face);
cv::Scalar eyeColor = CV_RGB(255,0,0);

if (kSmoothFaceImage) {

double sigma = kSmoothFaceFactor * face.width;
GaussianBlur( faceROI, faceROI, cv::Size( 0, 0 ), sigma);

}

//-- Find eye regions and draw them
int eye_region_width = face.width * (kEyePercentWidth/100.0);
int eye_region_height = face.width * (kEyePercentHeight/100.0);
int eye_region_top = face.height * (kEyePercentTop/100.0);
cv::Rect leftEyeRegion(face.width* (kEyePercentSide/100.0),
eye_region_top,eye_region_width,eye_region_height);
cv::Rect rightEyeRegion(face.width - eye_region_width - face.width*(kEyePercentSide/100.0),
eye_region_top,eye_region_width,eye_region_height);

cv::Rect maxContourRect;

if (true == getIrisArea(faceROI, leftEyeRegion, maxContourRect) )
{

cv::Rect leftEyeRect = cv::Rect(maxContourRect.x-maxContourRect.width, maxContourRect.y-maxContourRect.height, maxContourRect.width*3, maxContourRect.height*3);

leftEyeRect.x += leftEyeRegion.x;
leftEyeRect.y += leftEyeRegion.y;

leftPupil = cv::Point(leftEyeRect.x + leftEyeRect.width/2, leftEyeRect.y + leftEyeRect.height/2);

//rectangle(faceROI, leftEyeRect, 1234);

circle(faceROI, leftPupil, 6, eyeColor, 1, CV_AA);

} else {

leftPupil.x = leftPupil.y = -1;

}

if (true == getIrisArea(faceROI, rightEyeRegion, maxContourRect) )
{

cv::Rect rightEyeRect = cv::Rect(maxContourRect.x-maxContourRect.width, maxContourRect.y-maxContourRect.height, maxContourRect.width*3, maxContourRect.height*3);

rightEyeRect.x += rightEyeRegion.x;
rightEyeRect.y += rightEyeRegion.y;

rightPupil = cv::Point(rightEyeRect.x + rightEyeRect.width/2, rightEyeRect.y + rightEyeRect.height/2);

//rectangle(faceROI, rightEyeRect, 1234);

circle(faceROI, rightPupil, 6, eyeColor, 1, CV_AA);

} else {

rightPupil.x = rightPupil.y = -1;

}

rectangle(faceROI, leftEyeRegion, 1234);
rectangle(faceROI, rightEyeRegion, 1234);
imshow(face_window_name, faceROI);

}
```
...
Expand＞ ＜Close

Point(s): 2

0 lines left, continue to read

File list

Tips: You can preview the content of files by clicking file names^_^
Name Size Date
constants.h685.00 B2014-03-23 00:51
eye_track.sln879.00 B2014-01-12 12:47
eye_track.vcxproj5.52 kB2014-03-22 23:39
eye_track.vcxproj.filters1.49 kB2014-03-22 23:39
main.cpp2.52 kB2014-03-23 01:09
OPENCV_DEBUG.props883.00 B2014-01-14 18:35
OPENCV_RELEASE.props872.00 B2014-01-14 18:36
01.97 kB
track_eye.cpp6.28 kB2014-03-23 01:22
track_eye.h267.00 B2014-03-22 23:51
...
• Sent successfully!
• eye_track.zip
• 2 point

track_eye.cpp (550.50 kB)

Need 2 point

Get point immediately by PayPal

More(Debit card / Credit card / PayPal Credit / Online Banking)

Submit your source codes. Get more point

Don't have an account？ Register now
Need any help?
Mail to: support@codeforge.com

切换到中文版？

CodeForge Chinese Version
CodeForge English Version

^_^"Oops ...

Sorry!This guy is mysterious, its blog hasn't been opened, try another, please!

Warm tip!

Favorite by Ctrl+D