proper memory management, and tuning

This commit is contained in:
Harrison Deng 2018-05-08 19:58:29 -05:00
parent 31089cf647
commit 0efd3a02f7
13 changed files with 60 additions and 92 deletions

View File

@ -1,6 +1,6 @@
#include "BoundTracker.h" #include "BoundTracker.h"
BoundTracker::BoundTracker(int *lastKey, UI *ui) { BoundTracker::BoundTracker(std::shared_ptr<int> lastKey, std::shared_ptr<UI> ui) {
BoundTracker::lastKey = lastKey; BoundTracker::lastKey = lastKey;
BoundTracker::ui = ui; BoundTracker::ui = ui;
} }

View File

@ -3,18 +3,19 @@
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp> #include <opencv2/tracking.hpp>
#include "../UI.h" #include "../UI.h"
#include <memory>
class BoundTracker { class BoundTracker {
int *lastKey; std::shared_ptr<int> lastKey;
UI *ui; std::shared_ptr<UI> ui;
cv::Rect2d roi; cv::Rect2d roi;
unsigned queueSize = 20; unsigned queueSize = 20;
std::deque<cv::Rect2d> deadConsistency; std::deque<cv::Rect2d> deadConsistency;
cv::Ptr<cv::Tracker> tracker = cv::TrackerKCF::create();; cv::Ptr<cv::Tracker> tracker = cv::TrackerKCF::create();
public: public:
BoundTracker(int *lastKey, UI *ui); BoundTracker(std::shared_ptr<int> lastKey, std::shared_ptr<UI> ui);
void init(cv::Rect2d roi); void init(cv::Rect2d roi);
bool track(); bool track();
void setROI(cv::Rect2d roi); void setROI(cv::Rect2d roi);

View File

@ -1,6 +1,6 @@
#include "Confidence.h" #include "Confidence.h"
Confidence::Confidence(int *lastKey, UI *ui, unsigned validityLength, float similarity) { Confidence::Confidence(std::shared_ptr<int> lastKey, std::shared_ptr<UI> ui, unsigned validityLength, float similarity) {
queueLength = validityLength; queueLength = validityLength;
this->lastKey = lastKey; this->lastKey = lastKey;
this->ui = ui; this->ui = ui;

View File

@ -4,12 +4,13 @@
#include <queue> #include <queue>
#include <vector> #include <vector>
#include "../UI.h" #include "../UI.h"
#include <memory>
class Confidence { class Confidence {
float similarity; float similarity;
unsigned queueLength = 0; unsigned queueLength = 0;
int *lastKey; std::shared_ptr<int> lastKey;
UI *ui; std::shared_ptr<UI> ui;
bool drawBounds = false; bool drawBounds = false;
cv::Scalar boundColor {30, 30, 255}; cv::Scalar boundColor {30, 30, 255};
@ -17,7 +18,7 @@ public:
std::deque<std::vector<cv::Rect>> confidenceQueue; std::deque<std::vector<cv::Rect>> confidenceQueue;
std::vector<cv::Rect> confident; std::vector<cv::Rect> confident;
Confidence(int *lastKey, UI *ui, unsigned history = 5, float similarity = 0.75); Confidence(std::shared_ptr<int> lastKey, std::shared_ptr<UI> ui, unsigned history = 5, float similarity = 0.75);
bool check(std::vector<cv::Rect> contours); bool check(std::vector<cv::Rect> contours);
std::vector<cv::Rect> rectangleBounds() const; std::vector<cv::Rect> rectangleBounds() const;
void drawBoundsOnMat(cv::Mat &mat); void drawBoundsOnMat(cv::Mat &mat);

View File

@ -3,7 +3,7 @@
#include "../UI.h" #include "../UI.h"
#include <algorithm> #include <algorithm>
ContourAnalyzer::ContourAnalyzer(UI *ui, int *lastKey) { ContourAnalyzer::ContourAnalyzer(std::shared_ptr<UI> ui, std::shared_ptr<int> lastKey) {
this->ui = ui; this->ui = ui;
ui->UIListeners.push_back(this); ui->UIListeners.push_back(this);
this->lastKey = lastKey; 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)) { 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); double perimeter = cv::arcLength(contours[i], true);
cv::approxPolyDP(contours[i], contours[i], (epsilon/(float)1000)*perimeter, true); cv::approxPolyDP(contours[i], contours[i], (epsilon/(float)1000)*perimeter, true);
if ((contours[i].size() == 4) && (cv::isContourConvex(contours[i]))) { if ((contours[i].size() == 4) && (cv::isContourConvex(contours[i]))) {
if (prunedContours.size() != 0) { prunedContours.push_back(contours[i]);
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]);
}
} }
} }

View File

@ -1,21 +1,15 @@
/*
* ContourAnalyzer.h
*
* Created on: Apr 22, 2018
* Author: Yunyang
*/
#ifndef RECTANGLE_DETECTION_CONTOURANALYZER_H_ #ifndef RECTANGLE_DETECTION_CONTOURANALYZER_H_
#define RECTANGLE_DETECTION_CONTOURANALYZER_H_ #define RECTANGLE_DETECTION_CONTOURANALYZER_H_
#include <string> #include <string>
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
#include "../UI.h" #include "../UI.h"
#include "../UIListener.hpp" #include "../UIListener.hpp"
#include <memory>
class ContourAnalyzer: public UIListener { class ContourAnalyzer: public UIListener {
int *lastKey; std::shared_ptr<int> lastKey;
bool cannyRec = false, drawContours = false; bool cannyRec = false, drawContours = false;
UI *ui; std::shared_ptr<UI> ui;
std::vector<std::vector<cv::Point>> contours; std::vector<std::vector<cv::Point>> contours;
std::vector<std::vector<cv::Point>> inconsistentContours; std::vector<std::vector<cv::Point>> inconsistentContours;
std::vector<std::vector<cv::Point>> consistentContours; std::vector<std::vector<cv::Point>> consistentContours;
@ -29,13 +23,13 @@ public:
int binLower = 54; int binLower = 54;
int minSize = 0; int minSize = 0;
int minSizeScale = 18; int minSizeScale = 10;
int cannyLower = 45; int cannyLower = 42;
int cannyUpper = 3*cannyLower; int cannyUpper = 3*cannyLower;
int epsilon = 56; int epsilon = 56;
ContourAnalyzer(UI* ui, int *lastKey); ContourAnalyzer(std::shared_ptr<UI> ui, std::shared_ptr<int> lastKey);
virtual ~ContourAnalyzer(); virtual ~ContourAnalyzer();
cv::Scalar selectColor { 0, 255, 0 }; cv::Scalar selectColor { 0, 255, 0 };
cv::Scalar fontColor { 0, 0, 255 }; cv::Scalar fontColor { 0, 0, 255 };

View File

@ -1,32 +1,30 @@
#include "Ruler.h" #include "Ruler.h"
#include <sstream> #include <sstream>
Ruler::Ruler(UI *ui, int *lastKey) { Ruler::Ruler(std::shared_ptr<UI> ui, std::shared_ptr<int> lastKey) {
this->ui = ui; this->ui = ui;
this->lastKey = lastKey; this->lastKey = lastKey;
} }
void Ruler::update() { void Ruler::update() {
focalLength = estimateFocalLength(HFOV); focalLength = estimateFocalLength();
distance = estimateDistance(rect); distance = estimateDistance();
inputUpdate(); inputUpdate();
updateUI(); 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))); float fl = (ui->getWidth()/2.0) * (cos((HFOV * M_PI)/(180*2.0))/sin(HFOV*M_PI/(180*2.0)));
return fl; return fl;
} }
void Ruler::updateUI() { void Ruler::updateUI() {
if (inputtingVal) { 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 { } 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); 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() { void Ruler::toggleInput() {
@ -38,9 +36,9 @@ void Ruler::toggleInput() {
} }
} }
int Ruler::estimateDistance(cv::RotatedRect rect) { int Ruler::estimateDistance() {
if (rect.size.area() > 0) { if (detectedWidth > 0) {
return (givenWidth*focalLength) / rect.size.width; return (givenWidth*focalLength) /detectedWidth;
} else { } else {
return 0; return 0;
} }
@ -49,11 +47,17 @@ int Ruler::estimateDistance(cv::RotatedRect rect) {
void Ruler::inputUpdate() { void Ruler::inputUpdate() {
if (*lastKey == 13) { if (*lastKey == 13) {
toggleInput(); toggleInput();
decimal = false;
} }
if (inputtingVal) { if (inputtingVal) {
if (*lastKey >= 48 && *lastKey <= 57) { if (*lastKey >= 48 && *lastKey <= 57) {
char val = '0' + (*lastKey - 48); char val = '0' + (*lastKey - 48);
numBuild.push_back(val); numBuild.push_back(val);
} else if (*lastKey == 46 && decimal == false) {
char val = '.';
numBuild.push_back(val);
decimal = true;
} }
if (numBuild.size() > 0) { if (numBuild.size() > 0) {
std::string numString{numBuild.begin(), numBuild.end()}; std::string numString{numBuild.begin(), numBuild.end()};
@ -62,8 +66,8 @@ void Ruler::inputUpdate() {
} }
} }
void Ruler::updateRectangle(cv::RotatedRect rect) { void Ruler::setDetectedWidth(int width) {
this->rect = rect; detectedWidth = width;
} }
void Ruler::componentSetup() { void Ruler::componentSetup() {

View File

@ -2,28 +2,30 @@
#define RECTANGLE_RULER_H_ #define RECTANGLE_RULER_H_
#include "../UI.h" #include "../UI.h"
#include "../UIListener.hpp" #include "../UIListener.hpp"
#include <memory>
class Ruler: public UIListener { class Ruler: public UIListener {
cv::Point distanceTextPos {5, 60}; cv::Point distanceTextPos {5, 60};
cv::Point confTextPos {5, 75}; cv::Point confTextPos {5, 75};
cv::Scalar textFontColor {20, 20, 20}; cv::Scalar textFontColor {20, 20, 20};
cv::RotatedRect rect; bool decimal = false;
UI *ui; int detectedWidth = 0;
int *lastKey; std::shared_ptr<UI> ui;
std::shared_ptr<int> lastKey;
float distance = 0; float distance = 0;
float givenWidth = 0; float givenWidth = 0;
float focalLength = 0; float focalLength = 0;
float HFOV = 65; float HFOV = 60;
bool inputtingVal = false; bool inputtingVal = false;
std::deque<char> numBuild; std::deque<char> numBuild;
public: public:
Ruler(UI *ui, int *lastKey); Ruler(std::shared_ptr<UI> ui, std::shared_ptr<int> lastKey);
float estimateFocalLength(float HFOV); float estimateFocalLength();
int estimateDistance(cv::RotatedRect rect); int estimateDistance();
void update(); void update();
void updateRectangle(cv::RotatedRect rect); void setDetectedWidth(int width);
void componentSetup(); void componentSetup();
void updateUI(); void updateUI();
void toggleInput(); void toggleInput();

View File

@ -3,7 +3,7 @@
const std::string UI::NORMAL_WINDOW = "Normal"; const std::string UI::NORMAL_WINDOW = "Normal";
const std::string UI::DEBUG_WINDOW = "Debug"; const std::string UI::DEBUG_WINDOW = "Debug";
UI::UI(int *lastKey) { UI::UI(std::shared_ptr<int> lastKey) {
this->lastKey = lastKey; this->lastKey = lastKey;
} }

View File

@ -10,12 +10,13 @@
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
#include "UIListener.hpp" #include "UIListener.hpp"
#include "string" #include "string"
#include <memory>
class UI { class UI {
bool debug = false, showSlider = false; bool debug = false, showSlider = false;
unsigned lastDebugFrame = 0; unsigned lastDebugFrame = 0;
unsigned debugFrame = 0; unsigned debugFrame = 0;
int *lastKey; std::shared_ptr<int> lastKey;
int width = 0, height = 0; int width = 0, height = 0;
unsigned state = 0; unsigned state = 0;
std::vector<cv::Mat> frames = {cv::Mat()}; std::vector<cv::Mat> frames = {cv::Mat()};
@ -27,7 +28,7 @@ public:
static const std::string DEBUG_WINDOW; static const std::string DEBUG_WINDOW;
std::vector<UIListener *> UIListeners; std::vector<UIListener *> UIListeners;
UI(int *lastKey); UI(std::shared_ptr<int> lastKey);
void render(); void render();
void nextDebugFrame(); void nextDebugFrame();
cv::Mat* nextFrame(); cv::Mat* nextFrame();

View File

@ -6,14 +6,16 @@
#include "Rectangle/Confidence.h" #include "Rectangle/Confidence.h"
#include "Rectangle/BoundTracker.h" #include "Rectangle/BoundTracker.h"
#include "Rectangle/Ruler.h" #include "Rectangle/Ruler.h"
#include <memory>
enum State { enum State {
detection, track, cross_check detection, track, cross_check
}; };
State state = detection; State state = detection;
Webcam webcam = 0; Webcam webcam;
int *lastKey = new int(0); std::shared_ptr<int> lastKey {new int(0)};
UI *ui = new UI(lastKey); std::shared_ptr<UI> ui {new UI(lastKey)};
ContourAnalyzer ca { ui, lastKey }; ContourAnalyzer ca { ui, lastKey };
Confidence conf { lastKey, ui, 6, 0.78}; Confidence conf { lastKey, ui, 6, 0.78};
BoundTracker tracker { lastKey, ui }; BoundTracker tracker { lastKey, ui };
@ -39,7 +41,6 @@ void run() {
largest = rects[i]; largest = rects[i];
} }
} }
tracker.init(largest); tracker.init(largest);
state = track; state = track;
} }
@ -67,19 +68,16 @@ void run() {
ca.analyze(scaledSearchArea); ca.analyze(scaledSearchArea);
ca.convertContoursToBounds(); ca.convertContoursToBounds();
ca.convertContoursToRotatedBounds();
if (ca.getBounds().size() > 0) { if (ca.getBounds().size() > 0) {
cv::Rect largest; cv::Rect largest;
unsigned index;
for (unsigned i = 0; i < ca.getBounds().size(); i++) { for (unsigned i = 0; i < ca.getBounds().size(); i++) {
if (ca.getBounds()[i].area() > largest.area()) { if (ca.getBounds()[i].area() > largest.area()) {
largest = ca.getBounds()[i]; largest = ca.getBounds()[i];
index = i;
} }
} }
ruler.updateRectangle(ca.getRotatedBounds()[index]); ruler.setDetectedWidth(largest.width);
largest.x += scaledSearchArea.x; largest.x += scaledSearchArea.x;
largest.y += scaledSearchArea.y; largest.y += scaledSearchArea.y;
@ -114,7 +112,7 @@ void run() {
frameCount = 0; frameCount = 0;
} else { } else {
frameCount++; frameCount++;
if (frameCount > 30) { if (frameCount > 20) {
state = detection; state = detection;
frameCount = 0; frameCount = 0;
} }
@ -154,8 +152,6 @@ int main(int argc, char** argv) {
*lastKey = -1; *lastKey = -1;
} }
delete ui;
delete lastKey;
cv::destroyAllWindows(); cv::destroyAllWindows();
return 0; return 0;
} }

View File

@ -1,14 +1,6 @@
/*
* Webcam.cpp
*
* Created on: Apr 21, 2018
* Author: Yunyang
*/
#include "Webcam.h" #include "Webcam.h"
Webcam::Webcam(int webcamID) { Webcam::Webcam() {
stream = new cv::VideoCapture(webcamID);
stream->set(cv::CAP_PROP_FRAME_WIDTH, 1920); stream->set(cv::CAP_PROP_FRAME_WIDTH, 1920);
stream->set(cv::CAP_PROP_FRAME_HEIGHT, 1080); stream->set(cv::CAP_PROP_FRAME_HEIGHT, 1080);
} }
@ -26,6 +18,5 @@ cv::Mat Webcam::getFrame() const {
} }
Webcam::~Webcam() { Webcam::~Webcam() {
delete stream;
} }

View File

@ -10,11 +10,11 @@
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
class Webcam { class Webcam {
cv::VideoCapture* stream; std::unique_ptr<cv::VideoCapture> stream {new cv::VideoCapture{0}};
cv::Mat frame; cv::Mat frame;
bool webcamConnected = false; bool webcamConnected = false;
public: public:
Webcam(int webcamID); Webcam();
virtual ~Webcam(); virtual ~Webcam();
void update(); void update();