summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pupil-detect.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/pupil-detect.cpp b/pupil-detect.cpp
new file mode 100644
index 0000000..2a991a3
--- /dev/null
+++ b/pupil-detect.cpp
@@ -0,0 +1,58 @@
+/**
+ * Program to detect pupil, based on
+ * http://www.codeproject.com/Articles/137623/Pupil-or-Eyeball-Detection-and-Extraction-by-C-fro
+ * with some improvements.
+ */
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <cmath>
+
+int main(int argc, char** argv)
+{
+ // Load image
+ cv::Mat src = cv::imread("eye_image.jpg");
+ if (src.empty())
+ return -1;
+
+ // Invert the source image and convert to grayscale
+ cv::Mat gray;
+ cv::cvtColor(~src, gray, CV_BGR2GRAY);
+ cv::imwrite("1.jpg", gray);
+
+ // Convert to binary image by thresholding it
+ cv::threshold(gray, gray, 220, 255, cv::THRESH_BINARY);
+ cv::imwrite("2.jpg", gray);
+
+ // Find all contours
+ std::vector<std::vector<cv::Point> > contours;
+ std::vector<cv::Vec4i> hierarchy;
+ cv::findContours(gray.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
+ cv::imwrite("3.jpg", gray);
+
+ // Fill holes in each contour
+ cv::drawContours(gray, contours, -1, CV_RGB(255,255,255), -1);
+ cv::imwrite("4.jpg", gray);
+
+ for (int i = 0; i < contours.size(); i++)
+ {
+ double area = cv::contourArea(contours[i]);
+ cv::Rect rect = cv::boundingRect(contours[i]);
+ int radius = rect.width/2;
+
+ // If contour is big enough and has round shape
+ // Then it is the pupil
+ if (area >= 30 &&
+ std::abs(1 - ((double)rect.width / (double)rect.height)) <= 0.2 &&
+ std::abs(1 - (area / (CV_PI * std::pow(radius, 2)))) <= 0.2)
+ {
+ cv::circle(src, cv::Point(rect.x + radius, rect.y + radius), radius, CV_RGB(255,0,0), 2);
+ }
+ }
+
+ cv::imshow("image", src);
+ cv::imwrite("5.jpg", src);
+ cv::waitKey(0);
+
+ return 0;
+}
+