165 lines
3.3 KiB
C++
165 lines
3.3 KiB
C++
#include "FeatureExtractor.h"
|
|
|
|
|
|
|
|
FeatureExtractor::FeatureExtractor(vector<Point> 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_<double>(1, 7) << 1.0, convexHullBendingEnergy / 100.0, ar, cr, bendingEnergy / 10000.0, , perimeter / 10000.0);
|
|
ref = (Mat_<double>(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<Point> 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<int> hullsI(contour.size()); // Indices to contour points
|
|
vector<Vec4i> defects;
|
|
convexHull(contour, hullsI, false);
|
|
convexityDefects(contour, hullsI, defects);
|
|
|
|
return (double)defects.size();
|
|
}
|
|
|
|
void FeatureExtractor::findContour(Mat &image, vector<Point> &contour)
|
|
{
|
|
Mat canny_output;
|
|
vector<vector<Point> > contours;
|
|
vector<Vec4i> 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];
|
|
} |