93 lines
2.5 KiB
C++
Executable File
93 lines
2.5 KiB
C++
Executable File
/*
|
|
* ContourAnalyzer.cpp
|
|
*
|
|
* Created on: Apr 22, 2018
|
|
* Author: Yunyang
|
|
*/
|
|
|
|
#include "../Shape/ContourAnalyzer.h"
|
|
|
|
#include <cmath>
|
|
|
|
ContourAnalyzer::ContourAnalyzer() {
|
|
|
|
}
|
|
|
|
void ContourAnalyzer::setFrame(cv::Mat frame) {
|
|
ContourAnalyzer::originFrame = frame;
|
|
}
|
|
|
|
int ContourAnalyzer::analyze() {
|
|
prunedContours.clear();
|
|
|
|
cv::cvtColor(originFrame, stepFrames[0], cv::COLOR_BGR2GRAY);
|
|
cv::GaussianBlur(stepFrames[0], stepFrames[1], cv::Size(5, 5), 0);
|
|
cv::Canny(stepFrames[1], stepFrames[2], 35, 125);
|
|
cv::findContours(stepFrames[2], contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
|
|
|
|
for (unsigned i = 0; i < contours.size(); i++) {
|
|
double perimeter = cv::arcLength(contours[i], true);
|
|
cv::approxPolyDP(contours[i], contours[i], 0.04*perimeter, true);
|
|
if ((contours[i].size() == 4) && (cv::contourArea(contours[i]) > 81) && (cv::isContourConvex(contours[i]))) {
|
|
if (prunedContours.size() != 0) {
|
|
bool different = true;
|
|
for (unsigned comparedTo = 0; comparedTo < prunedContours.size(); comparedTo++) {
|
|
cv::Moments m1 = cv::moments(prunedContours[comparedTo]);
|
|
int cx1 = (m1.m10/m1.m00);
|
|
int cy1 = (m1.m01/m1.m00);
|
|
|
|
cv::Moments m2 = cv::moments(contours[i]);
|
|
int cx2 = (m2.m10/m2.m00);
|
|
int cy2 = (m2.m01/m2.m00);
|
|
|
|
if ((std::abs(cx1 - cx2) < 3) && (std::abs(cy1 - cy2) < 3)) {
|
|
different = false;
|
|
break;
|
|
}
|
|
}
|
|
if (different) {
|
|
prunedContours.insert(prunedContours.begin(), contours[i]);
|
|
}
|
|
} else {
|
|
prunedContours.insert(prunedContours.begin(), contours[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return contours.size();
|
|
}
|
|
|
|
void ContourAnalyzer::drawShapePositions(cv::Mat &frame) {
|
|
for (unsigned i = 0; i < prunedContours.size(); i++) {
|
|
cv::Moments m = cv::moments(prunedContours[i]);
|
|
int cx = (m.m10/m.m00);
|
|
int cy = (m.m01/m.m00);
|
|
cv::putText(frame, "rectangle", cv::Point{cx, cy}, cv::FONT_HERSHEY_PLAIN, 1, fontColor, 2);
|
|
cv::drawContours(frame, prunedContours, i, selectColor, 1);
|
|
}
|
|
}
|
|
|
|
std::string ContourAnalyzer::contourToString(std::vector<cv::Point> contour) {
|
|
switch (contour.size()) {
|
|
case 4:
|
|
if (cv::isContourConvex(contour)) {
|
|
return "rectangle";
|
|
}
|
|
/* no break */
|
|
default:
|
|
throw std::invalid_argument("Shape too complex!");
|
|
}
|
|
}
|
|
|
|
cv::Mat ContourAnalyzer::getDebugFrame(int step) const {
|
|
return stepFrames[step];
|
|
}
|
|
|
|
std::vector<cv::Rect> ContourAnalyzer::getBounds() const {
|
|
return bounds;
|
|
}
|
|
|
|
ContourAnalyzer::~ContourAnalyzer() {
|
|
}
|
|
|