proper memory management, and tuning
This commit is contained in:
parent
31089cf647
commit
0efd3a02f7
@ -1,6 +1,6 @@
|
||||
#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::ui = ui;
|
||||
}
|
||||
|
@ -3,18 +3,19 @@
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include "../UI.h"
|
||||
#include <memory>
|
||||
|
||||
class BoundTracker {
|
||||
int *lastKey;
|
||||
UI *ui;
|
||||
std::shared_ptr<int> lastKey;
|
||||
std::shared_ptr<UI> ui;
|
||||
cv::Rect2d roi;
|
||||
unsigned queueSize = 20;
|
||||
std::deque<cv::Rect2d> deadConsistency;
|
||||
|
||||
cv::Ptr<cv::Tracker> tracker = cv::TrackerKCF::create();;
|
||||
cv::Ptr<cv::Tracker> tracker = cv::TrackerKCF::create();
|
||||
|
||||
public:
|
||||
BoundTracker(int *lastKey, UI *ui);
|
||||
BoundTracker(std::shared_ptr<int> lastKey, std::shared_ptr<UI> ui);
|
||||
void init(cv::Rect2d roi);
|
||||
bool track();
|
||||
void setROI(cv::Rect2d roi);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#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;
|
||||
this->lastKey = lastKey;
|
||||
this->ui = ui;
|
||||
|
@ -4,12 +4,13 @@
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include "../UI.h"
|
||||
#include <memory>
|
||||
|
||||
class Confidence {
|
||||
float similarity;
|
||||
unsigned queueLength = 0;
|
||||
int *lastKey;
|
||||
UI *ui;
|
||||
std::shared_ptr<int> lastKey;
|
||||
std::shared_ptr<UI> ui;
|
||||
bool drawBounds = false;
|
||||
cv::Scalar boundColor {30, 30, 255};
|
||||
|
||||
@ -17,7 +18,7 @@ public:
|
||||
std::deque<std::vector<cv::Rect>> confidenceQueue;
|
||||
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);
|
||||
std::vector<cv::Rect> rectangleBounds() const;
|
||||
void drawBoundsOnMat(cv::Mat &mat);
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "../UI.h"
|
||||
#include <algorithm>
|
||||
|
||||
ContourAnalyzer::ContourAnalyzer(UI *ui, int *lastKey) {
|
||||
ContourAnalyzer::ContourAnalyzer(std::shared_ptr<UI> ui, std::shared_ptr<int> 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]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,21 +1,15 @@
|
||||
/*
|
||||
* ContourAnalyzer.h
|
||||
*
|
||||
* Created on: Apr 22, 2018
|
||||
* Author: Yunyang
|
||||
*/
|
||||
|
||||
#ifndef RECTANGLE_DETECTION_CONTOURANALYZER_H_
|
||||
#define RECTANGLE_DETECTION_CONTOURANALYZER_H_
|
||||
#include <string>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "../UI.h"
|
||||
#include "../UIListener.hpp"
|
||||
#include <memory>
|
||||
|
||||
class ContourAnalyzer: public UIListener {
|
||||
int *lastKey;
|
||||
std::shared_ptr<int> lastKey;
|
||||
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>> inconsistentContours;
|
||||
std::vector<std::vector<cv::Point>> 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> ui, std::shared_ptr<int> lastKey);
|
||||
virtual ~ContourAnalyzer();
|
||||
cv::Scalar selectColor { 0, 255, 0 };
|
||||
cv::Scalar fontColor { 0, 0, 255 };
|
||||
|
@ -1,32 +1,30 @@
|
||||
#include "Ruler.h"
|
||||
#include <sstream>
|
||||
|
||||
Ruler::Ruler(UI *ui, int *lastKey) {
|
||||
Ruler::Ruler(std::shared_ptr<UI> ui, std::shared_ptr<int> 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() {
|
||||
|
@ -2,28 +2,30 @@
|
||||
#define RECTANGLE_RULER_H_
|
||||
#include "../UI.h"
|
||||
#include "../UIListener.hpp"
|
||||
#include <memory>
|
||||
|
||||
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> ui;
|
||||
std::shared_ptr<int> lastKey;
|
||||
float distance = 0;
|
||||
float givenWidth = 0;
|
||||
float focalLength = 0;
|
||||
float HFOV = 65;
|
||||
float HFOV = 60;
|
||||
bool inputtingVal = false;
|
||||
std::deque<char> numBuild;
|
||||
|
||||
public:
|
||||
Ruler(UI *ui, int *lastKey);
|
||||
float estimateFocalLength(float HFOV);
|
||||
int estimateDistance(cv::RotatedRect rect);
|
||||
Ruler(std::shared_ptr<UI> ui, std::shared_ptr<int> lastKey);
|
||||
float estimateFocalLength();
|
||||
int estimateDistance();
|
||||
void update();
|
||||
void updateRectangle(cv::RotatedRect rect);
|
||||
void setDetectedWidth(int width);
|
||||
void componentSetup();
|
||||
void updateUI();
|
||||
void toggleInput();
|
||||
|
@ -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<int> lastKey) {
|
||||
this->lastKey = lastKey;
|
||||
}
|
||||
|
||||
|
5
src/UI.h
5
src/UI.h
@ -10,12 +10,13 @@
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "UIListener.hpp"
|
||||
#include "string"
|
||||
#include <memory>
|
||||
|
||||
class UI {
|
||||
bool debug = false, showSlider = false;
|
||||
unsigned lastDebugFrame = 0;
|
||||
unsigned debugFrame = 0;
|
||||
int *lastKey;
|
||||
std::shared_ptr<int> lastKey;
|
||||
int width = 0, height = 0;
|
||||
unsigned state = 0;
|
||||
std::vector<cv::Mat> frames = {cv::Mat()};
|
||||
@ -27,7 +28,7 @@ public:
|
||||
static const std::string DEBUG_WINDOW;
|
||||
|
||||
std::vector<UIListener *> UIListeners;
|
||||
UI(int *lastKey);
|
||||
UI(std::shared_ptr<int> lastKey);
|
||||
void render();
|
||||
void nextDebugFrame();
|
||||
cv::Mat* nextFrame();
|
||||
|
18
src/main.cpp
18
src/main.cpp
@ -6,14 +6,16 @@
|
||||
#include "Rectangle/Confidence.h"
|
||||
#include "Rectangle/BoundTracker.h"
|
||||
#include "Rectangle/Ruler.h"
|
||||
#include <memory>
|
||||
|
||||
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<int> lastKey {new int(0)};
|
||||
std::shared_ptr<UI> 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -10,11 +10,11 @@
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
class Webcam {
|
||||
cv::VideoCapture* stream;
|
||||
std::unique_ptr<cv::VideoCapture> stream {new cv::VideoCapture{0}};
|
||||
cv::Mat frame;
|
||||
bool webcamConnected = false;
|
||||
public:
|
||||
Webcam(int webcamID);
|
||||
Webcam();
|
||||
virtual ~Webcam();
|
||||
|
||||
void update();
|
||||
|
Loading…
Reference in New Issue
Block a user