/* * ContourAnalyzer.cpp * * Created on: Apr 22, 2018 * Author: Yunyang */ #include "../Shape/ContourAnalyzer.h" #include 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 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 ContourAnalyzer::getBounds() const { return bounds; } ContourAnalyzer::~ContourAnalyzer() { }