double detector::contour_ellipse_deviation_variance(Contour_2D& contour) { auto ellipse = cv::fitEllipse(contour); EllipseDistCalculator<double> ellipseDistance(toEllipse<double>(ellipse)); auto sum_function = [&](cv::Point & point) {return std::pow(std::abs(ellipseDistance(point.x, point.y)), 2.0);}; double point_distances = fun::sum(sum_function, contour); double fit_variance = point_distances / double(contour.size()); return fit_variance; };
std::vector<cv::Point> Detector2D::ellipse_true_support(Detector2DProperties& props,Ellipse& ellipse, double ellipse_circumference, std::vector<cv::Point>& raw_edges) { std::vector<cv::Point> support_pixels; EllipseDistCalculator<double> ellipseDistance(ellipse); for (auto& p : raw_edges) { double distance = std::abs(ellipseDistance((double)p.x, (double)p.y)); if (distance <= props.ellipse_true_support_min_dist) { support_pixels.emplace_back(p); } } return support_pixels; }
std::pair<ContourIndices, ContourIndices> detector::divide_strong_and_weak_contours( const Contours_2D& contours, const EllipseEvaluation2D& is_ellipse, const float ellipse_fit_treshold, const float strong_perimeter_ratio_range_min, const float strong_perimeter_ratio_range_max, const float strong_area_ratio_range_min, const float strong_area_ratio_range_max) { ContourIndices strong_contours, weak_contours; int index = 0; for (const auto& contour : contours) { if (contour.size() >= 5) { // because fitEllipse needs at least 5 points cv::RotatedRect ellipse = cv::fitEllipse(contour); //is this ellipse a plausible candidate for a pupil? if (is_ellipse(ellipse)) { auto e = toEllipse<double>(ellipse); EllipseDistCalculator<double> ellipseDistance(e); auto sum_function = [&](cv::Point & point) {return std::pow(std::abs(ellipseDistance(point.x, point.y)), 2);}; double point_distances = fun::sum(sum_function, contour); double fit_variance = point_distances / double(contour.size()); if (fit_variance < ellipse_fit_treshold) { auto ratio = ellipse_contour_support_ratio(e, contour); double area_ratio = ratio.first; double perimeter_ratio = ratio.second; // same as in original if (strong_perimeter_ratio_range_min <= perimeter_ratio && strong_perimeter_ratio_range_max >= perimeter_ratio && strong_area_ratio_range_min <= area_ratio && strong_area_ratio_range_max >= area_ratio) { strong_contours.push_back(index); // if (use_debug_image) // { // cv::polylines(debug_image, contour, false, mRoyalBlue_color, 4); // cv::ellipse(debug_image, ellipse, mBlue_color); // } } else { weak_contours.push_back(index); // if (use_debug_image) // { // cv::polylines(debug_image, contour, false, mBlue_color, 2); // cv::ellipse(debug_image, ellipse, mBlue_color); // } } } } } index++; } return std::make_pair(std::move(strong_contours), std::move(weak_contours)); }