diff --git a/src/Rectangle/BoundTracker.cpp b/src/Rectangle/BoundTracker.cpp index d66f22f..2c174b2 100755 --- a/src/Rectangle/BoundTracker.cpp +++ b/src/Rectangle/BoundTracker.cpp @@ -1,6 +1,6 @@ #include "BoundTracker.h" -BoundTracker::BoundTracker(int *lastKey, UI *ui) { +BoundTracker::BoundTracker(std::shared_ptr lastKey, std::shared_ptr ui) { BoundTracker::lastKey = lastKey; BoundTracker::ui = ui; } diff --git a/src/Rectangle/BoundTracker.h b/src/Rectangle/BoundTracker.h index cfba046..5e99aaf 100755 --- a/src/Rectangle/BoundTracker.h +++ b/src/Rectangle/BoundTracker.h @@ -3,18 +3,19 @@ #include #include #include "../UI.h" +#include class BoundTracker { - int *lastKey; - UI *ui; + std::shared_ptr lastKey; + std::shared_ptr ui; cv::Rect2d roi; unsigned queueSize = 20; std::deque deadConsistency; - cv::Ptr tracker = cv::TrackerKCF::create();; + cv::Ptr tracker = cv::TrackerKCF::create(); public: - BoundTracker(int *lastKey, UI *ui); + BoundTracker(std::shared_ptr lastKey, std::shared_ptr ui); void init(cv::Rect2d roi); bool track(); void setROI(cv::Rect2d roi); diff --git a/src/Rectangle/Confidence.cpp b/src/Rectangle/Confidence.cpp index 90ad821..bb9b8eb 100755 --- a/src/Rectangle/Confidence.cpp +++ b/src/Rectangle/Confidence.cpp @@ -1,6 +1,6 @@ #include "Confidence.h" -Confidence::Confidence(int *lastKey, UI *ui, unsigned validityLength, float similarity) { +Confidence::Confidence(std::shared_ptr lastKey, std::shared_ptr ui, unsigned validityLength, float similarity) { queueLength = validityLength; this->lastKey = lastKey; this->ui = ui; diff --git a/src/Rectangle/Confidence.h b/src/Rectangle/Confidence.h index 266dd43..fd6e706 100755 --- a/src/Rectangle/Confidence.h +++ b/src/Rectangle/Confidence.h @@ -4,12 +4,13 @@ #include #include #include "../UI.h" +#include class Confidence { float similarity; unsigned queueLength = 0; - int *lastKey; - UI *ui; + std::shared_ptr lastKey; + std::shared_ptr ui; bool drawBounds = false; cv::Scalar boundColor {30, 30, 255}; @@ -17,7 +18,7 @@ public: std::deque> confidenceQueue; std::vector confident; - Confidence(int *lastKey, UI *ui, unsigned history = 5, float similarity = 0.75); + Confidence(std::shared_ptr lastKey, std::shared_ptr ui, unsigned history = 5, float similarity = 0.75); bool check(std::vector contours); std::vector rectangleBounds() const; void drawBoundsOnMat(cv::Mat &mat); diff --git a/src/Rectangle/ContourAnalyzer.cpp b/src/Rectangle/ContourAnalyzer.cpp index 4381ed9..919d77d 100755 --- a/src/Rectangle/ContourAnalyzer.cpp +++ b/src/Rectangle/ContourAnalyzer.cpp @@ -3,7 +3,7 @@ #include "../UI.h" #include -ContourAnalyzer::ContourAnalyzer(UI *ui, int *lastKey) { +ContourAnalyzer::ContourAnalyzer(std::shared_ptr ui, std::shared_ptr lastKey) { this->ui = ui; ui->UIListeners.push_back(this); this->lastKey = lastKey; @@ -46,30 +46,8 @@ void ContourAnalyzer::removeRedundancy() { if ((cv::contourArea(contours[i]) > minSize) && (cv::contourArea(contours[i]) < (ui->currentFrame(0)->cols * ui->currentFrame(0)->rows) -25)) { double perimeter = cv::arcLength(contours[i], true); cv::approxPolyDP(contours[i], contours[i], (epsilon/(float)1000)*perimeter, true); - if ((contours[i].size() == 4) && (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]); - } + prunedContours.push_back(contours[i]); } } diff --git a/src/Rectangle/ContourAnalyzer.h b/src/Rectangle/ContourAnalyzer.h index c61c0a2..cbf7b15 100755 --- a/src/Rectangle/ContourAnalyzer.h +++ b/src/Rectangle/ContourAnalyzer.h @@ -1,21 +1,15 @@ -/* - * ContourAnalyzer.h - * - * Created on: Apr 22, 2018 - * Author: Yunyang - */ - #ifndef RECTANGLE_DETECTION_CONTOURANALYZER_H_ #define RECTANGLE_DETECTION_CONTOURANALYZER_H_ #include #include #include "../UI.h" #include "../UIListener.hpp" +#include class ContourAnalyzer: public UIListener { - int *lastKey; + std::shared_ptr lastKey; bool cannyRec = false, drawContours = false; - UI *ui; + std::shared_ptr ui; std::vector> contours; std::vector> inconsistentContours; std::vector> consistentContours; @@ -29,13 +23,13 @@ public: int binLower = 54; int minSize = 0; - int minSizeScale = 18; - int cannyLower = 45; + int minSizeScale = 10; + int cannyLower = 42; int cannyUpper = 3*cannyLower; int epsilon = 56; - ContourAnalyzer(UI* ui, int *lastKey); + ContourAnalyzer(std::shared_ptr ui, std::shared_ptr lastKey); virtual ~ContourAnalyzer(); cv::Scalar selectColor { 0, 255, 0 }; cv::Scalar fontColor { 0, 0, 255 }; diff --git a/src/Rectangle/Ruler.cpp b/src/Rectangle/Ruler.cpp index 0c32c85..2f0d0fd 100755 --- a/src/Rectangle/Ruler.cpp +++ b/src/Rectangle/Ruler.cpp @@ -1,32 +1,30 @@ #include "Ruler.h" #include -Ruler::Ruler(UI *ui, int *lastKey) { +Ruler::Ruler(std::shared_ptr ui, std::shared_ptr lastKey) { this->ui = ui; this->lastKey = lastKey; } void Ruler::update() { - focalLength = estimateFocalLength(HFOV); - distance = estimateDistance(rect); + focalLength = estimateFocalLength(); + distance = estimateDistance(); inputUpdate(); updateUI(); } -float Ruler::estimateFocalLength(float HFOV) { +float Ruler::estimateFocalLength() { float fl = (ui->getWidth()/2.0) * (cos((HFOV * M_PI)/(180*2.0))/sin(HFOV*M_PI/(180*2.0))); return fl; } void Ruler::updateUI() { if (inputtingVal) { - cv::putText(*(ui->drawnFrame()), ("Given width: " + std::to_string(givenWidth)), confTextPos, cv::FONT_HERSHEY_PLAIN, 0.7, textFontColor, 2); + cv::putText(*(ui->drawnFrame()), ("Given width: " + std::to_string(givenWidth) + "cm"), confTextPos, cv::FONT_HERSHEY_PLAIN, 0.7, textFontColor, 2); } else { - cv::putText(*(ui->drawnFrame()), ("Given width: " + std::to_string(givenWidth)), confTextPos, cv::FONT_HERSHEY_PLAIN, 0.7, textFontColor); + cv::putText(*(ui->drawnFrame()), ("Given width: " + std::to_string(givenWidth) + "cm"), confTextPos, cv::FONT_HERSHEY_PLAIN, 0.7, textFontColor); } cv::putText(*(ui->drawnFrame()), ("distance: " + std::to_string(distance) + "cm"), distanceTextPos, cv::FONT_HERSHEY_PLAIN, 0.7, textFontColor); - - std::cout << "focal length: " + std::to_string(focalLength) << std::endl; } void Ruler::toggleInput() { @@ -38,9 +36,9 @@ void Ruler::toggleInput() { } } -int Ruler::estimateDistance(cv::RotatedRect rect) { - if (rect.size.area() > 0) { - return (givenWidth*focalLength) / rect.size.width; +int Ruler::estimateDistance() { + if (detectedWidth > 0) { + return (givenWidth*focalLength) /detectedWidth; } else { return 0; } @@ -49,11 +47,17 @@ int Ruler::estimateDistance(cv::RotatedRect rect) { void Ruler::inputUpdate() { if (*lastKey == 13) { toggleInput(); + decimal = false; + } if (inputtingVal) { if (*lastKey >= 48 && *lastKey <= 57) { char val = '0' + (*lastKey - 48); numBuild.push_back(val); + } else if (*lastKey == 46 && decimal == false) { + char val = '.'; + numBuild.push_back(val); + decimal = true; } if (numBuild.size() > 0) { std::string numString{numBuild.begin(), numBuild.end()}; @@ -62,8 +66,8 @@ void Ruler::inputUpdate() { } } -void Ruler::updateRectangle(cv::RotatedRect rect) { - this->rect = rect; +void Ruler::setDetectedWidth(int width) { + detectedWidth = width; } void Ruler::componentSetup() { diff --git a/src/Rectangle/Ruler.h b/src/Rectangle/Ruler.h index 6290a0a..374ec53 100755 --- a/src/Rectangle/Ruler.h +++ b/src/Rectangle/Ruler.h @@ -2,28 +2,30 @@ #define RECTANGLE_RULER_H_ #include "../UI.h" #include "../UIListener.hpp" +#include class Ruler: public UIListener { cv::Point distanceTextPos {5, 60}; cv::Point confTextPos {5, 75}; cv::Scalar textFontColor {20, 20, 20}; - cv::RotatedRect rect; - UI *ui; - int *lastKey; + bool decimal = false; + int detectedWidth = 0; + std::shared_ptr ui; + std::shared_ptr lastKey; float distance = 0; float givenWidth = 0; float focalLength = 0; - float HFOV = 65; + float HFOV = 60; bool inputtingVal = false; std::deque numBuild; public: - Ruler(UI *ui, int *lastKey); - float estimateFocalLength(float HFOV); - int estimateDistance(cv::RotatedRect rect); + Ruler(std::shared_ptr ui, std::shared_ptr lastKey); + float estimateFocalLength(); + int estimateDistance(); void update(); - void updateRectangle(cv::RotatedRect rect); + void setDetectedWidth(int width); void componentSetup(); void updateUI(); void toggleInput(); diff --git a/src/UI.cpp b/src/UI.cpp index 0060c73..582071a 100755 --- a/src/UI.cpp +++ b/src/UI.cpp @@ -3,7 +3,7 @@ const std::string UI::NORMAL_WINDOW = "Normal"; const std::string UI::DEBUG_WINDOW = "Debug"; -UI::UI(int *lastKey) { +UI::UI(std::shared_ptr lastKey) { this->lastKey = lastKey; } diff --git a/src/UI.h b/src/UI.h index 904717d..5654d9c 100755 --- a/src/UI.h +++ b/src/UI.h @@ -10,12 +10,13 @@ #include #include "UIListener.hpp" #include "string" +#include class UI { bool debug = false, showSlider = false; unsigned lastDebugFrame = 0; unsigned debugFrame = 0; - int *lastKey; + std::shared_ptr lastKey; int width = 0, height = 0; unsigned state = 0; std::vector frames = {cv::Mat()}; @@ -27,7 +28,7 @@ public: static const std::string DEBUG_WINDOW; std::vector UIListeners; - UI(int *lastKey); + UI(std::shared_ptr lastKey); void render(); void nextDebugFrame(); cv::Mat* nextFrame(); diff --git a/src/main.cpp b/src/main.cpp index 8f341f1..126a045 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,14 +6,16 @@ #include "Rectangle/Confidence.h" #include "Rectangle/BoundTracker.h" #include "Rectangle/Ruler.h" +#include + enum State { detection, track, cross_check }; State state = detection; -Webcam webcam = 0; -int *lastKey = new int(0); -UI *ui = new UI(lastKey); +Webcam webcam; +std::shared_ptr lastKey {new int(0)}; +std::shared_ptr ui {new UI(lastKey)}; ContourAnalyzer ca { ui, lastKey }; Confidence conf { lastKey, ui, 6, 0.78}; BoundTracker tracker { lastKey, ui }; @@ -39,7 +41,6 @@ void run() { largest = rects[i]; } } - tracker.init(largest); state = track; } @@ -67,19 +68,16 @@ void run() { ca.analyze(scaledSearchArea); ca.convertContoursToBounds(); - ca.convertContoursToRotatedBounds(); if (ca.getBounds().size() > 0) { cv::Rect largest; - unsigned index; for (unsigned i = 0; i < ca.getBounds().size(); i++) { if (ca.getBounds()[i].area() > largest.area()) { largest = ca.getBounds()[i]; - index = i; } } - ruler.updateRectangle(ca.getRotatedBounds()[index]); + ruler.setDetectedWidth(largest.width); largest.x += scaledSearchArea.x; largest.y += scaledSearchArea.y; @@ -114,7 +112,7 @@ void run() { frameCount = 0; } else { frameCount++; - if (frameCount > 30) { + if (frameCount > 20) { state = detection; frameCount = 0; } @@ -154,8 +152,6 @@ int main(int argc, char** argv) { *lastKey = -1; } - delete ui; - delete lastKey; cv::destroyAllWindows(); return 0; } diff --git a/src/webcam/Webcam.cpp b/src/webcam/Webcam.cpp index 3d32ebe..6b6033e 100755 --- a/src/webcam/Webcam.cpp +++ b/src/webcam/Webcam.cpp @@ -1,14 +1,6 @@ -/* - * Webcam.cpp - * - * Created on: Apr 21, 2018 - * Author: Yunyang - */ - #include "Webcam.h" -Webcam::Webcam(int webcamID) { - stream = new cv::VideoCapture(webcamID); +Webcam::Webcam() { stream->set(cv::CAP_PROP_FRAME_WIDTH, 1920); stream->set(cv::CAP_PROP_FRAME_HEIGHT, 1080); } @@ -26,6 +18,5 @@ cv::Mat Webcam::getFrame() const { } Webcam::~Webcam() { - delete stream; } diff --git a/src/webcam/Webcam.h b/src/webcam/Webcam.h index a5b7dc1..568865c 100755 --- a/src/webcam/Webcam.h +++ b/src/webcam/Webcam.h @@ -10,11 +10,11 @@ #include class Webcam { - cv::VideoCapture* stream; + std::unique_ptr stream {new cv::VideoCapture{0}}; cv::Mat frame; bool webcamConnected = false; public: - Webcam(int webcamID); + Webcam(); virtual ~Webcam(); void update();