From e4d755c00d8cca674e3f57d9711d8622a7ce7e63 Mon Sep 17 00:00:00 2001 From: Epicalert Date: Mon, 7 Jun 2021 02:05:48 +0800 Subject: [PATCH] Improve iris detection This commit makes the following changes to the iris detection: - Use Scharr instead os Sobel algorithm for image gradient - Apply Gaussian blur to eye image before processing - Scale down the eye image if too large --- src/cv.cpp | 6 ++---- src/eye.cpp | 23 ++++++++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/cv.cpp b/src/cv.cpp index 146ca14..dfdee0d 100644 --- a/src/cv.cpp +++ b/src/cv.cpp @@ -112,7 +112,8 @@ void cvFrame() { //get ROI for eyes float eyeWidth = landmarks[biggestFace][45].x - landmarks[biggestFace][42].x; - cv::Rect eyeRect(landmarks[biggestFace][42].x, landmarks[biggestFace][42].y - eyeWidth / 2, eyeWidth, eyeWidth); + cv::Rect eyeRect(landmarks[biggestFace][42].x, + landmarks[biggestFace][42].y - eyeWidth / 2, eyeWidth, eyeWidth); cv::rectangle(frame, eyeRect, cv::Scalar(255, 255, 255)); @@ -121,9 +122,6 @@ void cvFrame() { glm::vec2 eyeVector = eyeDirection(eyeROI); - cv::imshow("eye", eyeROI); - cv::waitKey(1); - //send control information to graphics float faceSize = landmarks[biggestFace][14].x - landmarks[biggestFace][2].x; diff --git a/src/eye.cpp b/src/eye.cpp index ead36e7..75514fd 100644 --- a/src/eye.cpp +++ b/src/eye.cpp @@ -55,16 +55,22 @@ cv::Point2f derivativeFunction(cv::Point2f c, cv::Mat gX, cv::Mat gY) { } glm::vec2 eyeDirection(cv::Mat roi) { - cv::Mat gX, gY; - cv::Sobel(roi, gX, CV_32F, 1, 0); - cv::Sobel(roi, gY, CV_32F, 0, 1); + cv::Mat gX, gY, eyeMat; + if(roi.rows > 32) { + cv::pyrDown(roi, eyeMat, cv::Size(roi.cols / 2, roi.rows / 2)); + } else { + cv::GaussianBlur(roi, eyeMat, cv::Size(7,7), 1); + } - float stepSize = roi.rows / 10; + cv::Scharr(eyeMat, gX, CV_32F, 1, 0); + cv::Scharr(eyeMat, gY, CV_32F, 0, 1); + + float stepSize = eyeMat.rows / 10; float maxVal = 0; cv::Point2f irisPosition; for(int i = 0; i < 32; i++) { - cv::Point2f c(std::rand() % roi.cols, std::rand() % roi.rows); //start at a random point + cv::Point2f c(std::rand() % eyeMat.cols, std::rand() % eyeMat.rows); //start at a random point float prevVal = 0; for(int j = 0; j < 8; j++) { @@ -74,7 +80,7 @@ glm::vec2 eyeDirection(cv::Mat roi) { for(int k = 0; k < 6; k++) { cv::Point2f newC = c + gradient * stepSize; - if (newC.x < 0 || newC.x > roi.cols || newC.y < 0 || newC.y > roi.rows) continue; + if (newC.x < 0 || newC.x > eyeMat.cols || newC.y < 0 || newC.y > eyeMat.rows) continue; float newVal = objectiveFunction(newC, gX, gY); if (newVal > prevVal) { @@ -95,7 +101,10 @@ glm::vec2 eyeDirection(cv::Mat roi) { } } - cv::drawMarker(roi, irisPosition, cv::Scalar(128,128,128)); + cv::drawMarker(eyeMat, irisPosition, cv::Scalar(128,128,128)); + + cv::imshow("eye", eyeMat); + cv::waitKey(1); // convert result to vector for graphics return glm::vec2(