Quantcast
Channel: OpenCV Q&A Forum - RSS feed
Viewing all articles
Browse latest Browse all 41027

What is the right/best way for Eye detection ?

$
0
0
I want to detect eyes inside a detected face in webcam footage. I am using haarcascade eye and split eye for detecting eyes. But the eye detection is too much unstable. The detected rectangle is always scaling, moving around and half of the time not detecting anything. It's too unstable for aligning and cropping the face correctly. Am I doing something wrong or is there any better way of eye detection? I am currently following the Mastering opencv books Face Recognition formula. Heres my code - Mat topLeftOfFace; Mat topRightOfFace; //Getting the LeftEYe and RIghtEYe Portions of Images -- getEyeRegions(biggestFace,"eye", topLeftOfFace, topRightOfFace,leftX,rightX,topY); //Dtecting the Left Eye Cascade newScale = topLeftOfFace.cols; Rect leftEye = detectCascadeSingle(topLeftOfFace, eyeDetector, newScale); if (leftEye.width <= 0){ getEyeRegions(biggestFace, "split_eye", topLeftOfFace, Mat(0,0,CV_8U),leftX,rightX,topY); newScale = topLeftOfFace.cols; leftEye = detectCascadeSingle(topLeftOfFace, leftEyeDetector, newScale); } Point leftEyeCenter = Point(-1,-1); if (leftEye.width >= 0){ leftEyeCenter.x = leftEye.x + leftEye.width / 2 + leftX; leftEyeCenter.y = leftEye.y + leftEye.height / 2 + topY; } //Detecting the RIght Eye cascade\ newScale = topRightOfFace.cols; Rect rightEye = detectCascadeSingle(topRightOfFace, eyeDetector, newScale); if (rightEye.width <= 0){ getEyeRegions(biggestFace, "split_eye", Mat(0, 0, CV_8U), topRightOfFace,leftX, rightX, topY); newScale = topRightOfFace.cols; rightEye = detectCascadeSingle(topRightOfFace, rightEyeDetector, newScale); } Point rightEyeCenter = Point(-1, -1); if (rightEye.width > 0){ rightEyeCenter.x = rightEye.x + rightEye.width / 2 + rightX; rightEyeCenter.y = rightEye.y + rightEye.height / 2 + topY; } And the getEyeRegion Function - void getEyeRegions(Mat biggestFace,string mode, Mat &topLeftOfFace, Mat &topRightOfFace, int &leftX, int &rightX, int &topY){ int widthX; int heightY; float EYE_SX; float EYE_SY; float EYE_SW; float EYE_SH; if (mode == "eye"){ EYE_SX = 0.16; EYE_SY = 0.26; EYE_SW = 0.30; EYE_SH = 0.28; } else if (mode == "split_eye"){ EYE_SX = 0.12; EYE_SY = 0.17; EYE_SW = 0.37; EYE_SH = 0.36; } leftX = cvRound(biggestFace.cols * EYE_SX); topY = cvRound(biggestFace.rows * EYE_SY); widthX = cvRound(biggestFace.cols * EYE_SW); heightY = cvRound(biggestFace.rows * EYE_SH); rightX = cvRound(biggestFace.cols * (1.0 - EYE_SX - EYE_SW)); topLeftOfFace = biggestFace(Rect(leftX, topY, widthX, heightY)); topRightOfFace = biggestFace(Rect(rightX, topY, widthX, heightY)); The detectCascadeSingle Function - cv::Rect detectCascadeSingle(Mat img, CascadeClassifier faceDetector, int scaledWidth){ if (img.channels() == 3){ cvtColor(img, img, CV_BGR2GRAY); } else if (img.channels() == 4){ cvtColor(img, img, CV_BGRA2GRAY); } int DETECTION_WIDTH = scaledWidth; float scale; scale = img.cols / DETECTION_WIDTH; if (img.cols > DETECTION_WIDTH){ int scaledHeight = cvRound(img.rows / scale); resize(img, img, Size(DETECTION_WIDTH, scaledHeight)); } //Image historgram equalization Mat equalizedImg; equalizeHist(img, img); int flags = CASCADE_SCALE_IMAGE; int biggestFlag = CASCADE_FIND_BIGGEST_OBJECT | CASCADE_DO_ROUGH_SEARCH; Size minFeatureSize(5, 5); float searchScaleFactor = 1.1f; int minNeighbors = 4; std::vector faces; faceDetector.detectMultiScale(img, faces, searchScaleFactor, minNeighbors, biggestFlag, minFeatureSize); if (img.cols > DETECTION_WIDTH){ for (int i = 0; i < (int)faces.size(); i++){ faces[i].x = cvRound(faces[i].x * scale); faces[i].y = cvRound(faces[i].y * scale); faces[i].width = cvRound(faces[i].width * scale); faces[i].height = cvRound(faces[i].height * scale); } } //Keeping the face inside the border for (int i = 0; i < (int)faces.size(); i++){ if (faces[i].x < 0){ faces[i].x = 0; } if (faces[i].y < 0){ faces[i].y = 0; } if (faces[i].x + faces[i].width > img.cols){ faces[i].x = img.cols - faces[i].width; } if (faces[i].y + faces[i].height > img.rows){ faces[i].y = img.rows - faces[i].height; } } cv::Rect biggestRect(0, 0, 0, 0); if (faces.size() >= 1){ for (size_t i = 0; i < faces.size(); ++i) { cv::Rect rect = faces[i]; if (rect.width > biggestRect.width) { biggestRect = rect; } } } return biggestRect; }

Viewing all articles
Browse latest Browse all 41027

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>