#include "FeatureExtractor.h" FeatureExtractor::FeatureExtractor(vector contour) { FeatureExtractor::contour = contour; rect = minAreaRect(contour); } FeatureExtractor::~FeatureExtractor() { } void FeatureExtractor::Extract(Mat &ref) { double ar = AspectRatio(); double cr = Circularity(); double bendingEnergy = getBendingEnergy(); double convexHullBendingEnergy = getConvexHullBendingEnergy(); double radius = getMinEnclosingCircleRadius(); double perimeter = getPerimeter(); double numDefects = convexDefects(); //ref = (Mat_(1, 7) << 1.0, convexHullBendingEnergy / 100.0, ar, cr, bendingEnergy / 10000.0, , perimeter / 10000.0); ref = (Mat_(1, 5) << 1.0, ar, cr / 10.0, convexHullBendingEnergy / 100.0, numDefects / 100.0); } double FeatureExtractor::AspectRatio() { double ar = 0; if(rect.size.width > rect.size.height) ar = (rect.size.height / rect.size.width); else ar = (rect.size.width / rect.size.height); return ar; } double FeatureExtractor::Circularity() { double radius = getMinEnclosingCircleRadius(); double carea = radius * radius * M_PI; double rectarea = rect.size.width * rect.size.height; double cir = carea / rectarea; return cir; } RotatedRect FeatureExtractor::Rectangle() { return rect; } double FeatureExtractor::getMinEnclosingCircleRadius() { float radius; Point2f center; minEnclosingCircle(contour, center, radius); double rad = (double)radius; return rad; } double FeatureExtractor::getPerimeter() { double per = arcLength(contour, true); return per; } double FeatureExtractor::getBendingEnergy() { double energy = 0; int dir = 0; int prevdir = 0; Point previousPoint = contour[contour.size() - 1]; for (Point p : contour) { dir = discoverNextRelativeDirection(previousPoint, p); energy += (dir - prevdir + 8) % 8; prevdir = dir; previousPoint = p; } return energy; } double FeatureExtractor::getConvexHullBendingEnergy() { vector convex; convexHull(contour, convex); double energy = 0; int dir = 0; int prevdir = 0; Point previousPoint = convex[convex.size() - 1]; for (Point p : convex) { dir = discoverNextRelativeDirection(previousPoint, p); energy += (dir - prevdir + 8) % 8; prevdir = dir; previousPoint = p; } return energy; } int FeatureExtractor::discoverNextRelativeDirection(const cv::Point &pos, const cv::Point &target) { for (int i = 0; i < 8; i++) { int dir = i; int newX = pos.x + rotateX[dir]; int newY = pos.y + rotateY[dir]; if (target.x == newX && target.y == newY) return dir; } return -1; } double FeatureExtractor::convexDefects() { vector hullsI(contour.size()); // Indices to contour points vector defects; convexHull(contour, hullsI, false); convexityDefects(contour, hullsI, defects); return (double)defects.size(); } void FeatureExtractor::findContour(Mat &image, vector &contour) { Mat canny_output; vector > contours; vector hierarchy; Canny(image, canny_output, 20, 150, 3); findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); int large = 0; int contouridx = -1; for (int i = 0; i < contours.size(); i++) { double a = arcLength(contours[i], false); if (a > large) { large = a; contouridx = i; } } contour = contours[contouridx]; }