| 287 | } |
| 288 | |
| 289 | static void correctIris(const Mat& image, std::vector<Point2f>& points) |
| 290 | { |
| 291 | assert(image.channels() == 1); |
| 292 | RoiInfo eye_info_r = calcuateEyeRegionInfo_r(points); |
| 293 | RoiInfo eye_info_l = calcuateEyeRegionInfo_l(points); |
| 294 | |
| 295 | Mat eye_r = image(Rect(eye_info_r.origion, eye_info_r.mask.size())); |
| 296 | Mat eye_l = image(Rect(eye_info_l.origion, eye_info_l.mask.size())); |
| 297 | |
| 298 | // roughly estimate iris radius |
| 299 | const int iris_indices_r[] = {35, 37, 39, 41}; |
| 300 | const int iris_indices_l[] = {45, 47, 49, 51}; |
| 301 | float iris_r_radius = venus::distance(points[42], points[iris_indices_r[0]]); |
| 302 | for(size_t i = 1; i < NELEM(iris_indices_r); ++i) |
| 303 | { |
| 304 | float dist = venus::distance(points[42], points[iris_indices_r[i]]); |
| 305 | if(iris_r_radius > dist) |
| 306 | iris_r_radius = dist; |
| 307 | } |
| 308 | |
| 309 | float iris_l_radius = venus::distance(points[43], points[iris_indices_l[0]]); |
| 310 | for(size_t i = 1; i < NELEM(iris_indices_l); ++i) |
| 311 | { |
| 312 | float dist = venus::distance(points[43], points[iris_indices_l[i]]); |
| 313 | if(iris_l_radius > dist) |
| 314 | iris_l_radius = dist; |
| 315 | } |
| 316 | |
| 317 | // Morphological opening is performed to remove glint. |
| 318 | int morph_radius = 1; |
| 319 | int morph_size = morph_radius * 2 + 1; |
| 320 | Mat element = getStructuringElement(cv::MORPH_RECT, Size(morph_size, morph_size), Point(morph_radius, morph_radius)); |
| 321 | Mat image_processed; |
| 322 | morphologyEx(eye_r, eye_r, cv::MORPH_OPEN, element); |
| 323 | morphologyEx(eye_l, eye_l, cv::MORPH_OPEN, element); |
| 324 | |
| 325 | // http://stackoverflow.com/questions/10716464/what-are-the-correct-usage-parameter-values-for-houghcircles-in-opencv-for-iris |
| 326 | const float tolerance = 0.666f; |
| 327 | std::vector<cv::Vec3f> circles_r, circles_l; |
| 328 | for(int i = 8; i < 20; ++i) |
| 329 | { |
| 330 | cv::HoughCircles(eye_r, circles_r, cv::HOUGH_GRADIENT, 1, 30, 100, i, iris_r_radius*tolerance, iris_r_radius/tolerance); |
| 331 | if(circles_r.size() <= 1) |
| 332 | break; |
| 333 | } |
| 334 | for(int i = 8; i < 20; ++i) |
| 335 | { |
| 336 | cv::HoughCircles(eye_l, circles_l, cv::HOUGH_GRADIENT, 1, 30, 100, i, iris_l_radius*tolerance, iris_l_radius/tolerance); |
| 337 | if(circles_l.size() <= 1) |
| 338 | break; |
| 339 | } |
| 340 | |
| 341 | if(circles_r.size() > 1 || circles_l.size() > 1) |
| 342 | LOGW("multiple circles detected, need to be only one"); |
| 343 | |
| 344 | /* |
| 345 | 36 46 |
| 346 | 37 35 45 47 |
nothing calls this directly
no test coverage detected