Skip to content

Commit 032cb03

Browse files
author
Hauke Jürgen Mönck
committed
Restructured code, added Rectification
TODO: Code is very ugly and the view does tasks it is NOT supposed to do, i.e. update all rectification relevant information. Fix this! NOTE: I'm aware of plenty more ugly perks (documentation lack, code structure), just wait for it...
1 parent 40104b3 commit 032cb03

63 files changed

Lines changed: 778 additions & 888 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,6 @@ CMakeFiles
7878
/BioTracker/Plugin/BioTrackerPlugin/BioTrackerPlugin.pro.user.b485f2d
7979
/BioTracker/CoreApp/BioTracker/BioTracker.pro.user.b485f2d
8080
/BioTracker/Plugin/BioTrackerPlugin/BioTrackerPlugin.pro.user.b485f2d
81+
/BioTracker/x64/Debug/ALL_BUILD/*.cache
82+
/BioTracker/x64/Release/ALL_BUILD/*.cache
83+
/BioTracker/CoreApp/BioTracker/TrackingOutput.txt

BioTracker/CoreApp/BioTracker/View/MainWindow.ui

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@
126126
<bool>true</bool>
127127
</property>
128128
<property name="sizePolicy">
129-
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
129+
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
130130
<horstretch>0</horstretch>
131-
<verstretch>0</verstretch>
131+
<verstretch>100</verstretch>
132132
</sizepolicy>
133133
</property>
134134
<property name="minimumSize">
@@ -137,6 +137,12 @@
137137
<height>0</height>
138138
</size>
139139
</property>
140+
<property name="maximumSize">
141+
<size>
142+
<width>16777215</width>
143+
<height>200</height>
144+
</size>
145+
</property>
140146
</widget>
141147
</item>
142148
</layout>
@@ -153,7 +159,7 @@
153159
<x>0</x>
154160
<y>0</y>
155161
<width>982</width>
156-
<height>22</height>
162+
<height>21</height>
157163
</rect>
158164
</property>
159165
<widget class="QMenu" name="menuFile">
@@ -320,8 +326,8 @@
320326
<rect>
321327
<x>0</x>
322328
<y>0</y>
323-
<width>180</width>
324-
<height>545</height>
329+
<width>184</width>
330+
<height>554</height>
325331
</rect>
326332
</property>
327333
<property name="sizePolicy">

BioTracker/Plugin/BioTrackerPlugin/BioTrackerPlugin.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "Controller/ControllerTrackingAlgorithm.h"
55
#include "Controller/ControllerTrackedComponent.h"
66

7+
#include "View\TrackedElementView.h"
8+
79
BioTrackerPlugin::BioTrackerPlugin() {
810
}
911

@@ -39,6 +41,11 @@ void BioTrackerPlugin::connectInterfaces() {
3941
QObject::connect(ctrAlg, &ControllerTrackingAlgorithm::emitCvMat, this, &BioTrackerPlugin::receiveCvMatFromController);
4042

4143
QObject::connect(ctrAlg, &ControllerTrackingAlgorithm::emitTrackingDone, this, &BioTrackerPlugin::receiveTrackingDone);
44+
45+
//TODO Hauke I'm not sure if these are the correct partners
46+
//BioTrackerTrackingAlgorithm *trackingAlg = qobject_cast<BioTrackerTrackingAlgorithm *>(m_TrackerController->getModel());
47+
//TrackedElementView *view = (TrackedElementView *)(m_ComponentController->getView());
48+
//QObject::connect(view, &TrackedElementView::emitUpdateCornersChanged, trackingAlg, &BioTrackerTrackingAlgorithm::updateCorner);
4249
}
4350

4451
void BioTrackerPlugin::receiveCurrentFrameFromMainApp(std::shared_ptr<cv::Mat> mat, uint frameNumber) {

BioTracker/Plugin/BioTrackerPlugin/Controller/ControllerTrackedComponent.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "ControllerTrackedComponent.h"
22
#include "Model/TrackedComponents/TrackedElement.h"
3+
#include "Model/TrackedComponents/TrackingRectElement.h"
34
#include "Model/TrackedComponents/TrackedTrajectory.h"
45
#include "View/TrackedElementView.h"
56

@@ -21,7 +22,6 @@ void ControllerTrackedComponent::connectModelToController()
2122

2223
void ControllerTrackedComponent::connectControllerToController()
2324
{
24-
2525
}
2626

2727
void createTrajectories(int count, TrackedTrajectory* all) {
@@ -39,7 +39,27 @@ void createTrajectories(int count, TrackedTrajectory* all) {
3939
void ControllerTrackedComponent::createModel()
4040
{
4141
TrackedTrajectory *t = new TrackedTrajectory(this, "All");
42+
43+
//Add default trajectories
4244
createTrajectories(2, t);
45+
46+
//Add rect corners for rectification
47+
TrackingRectElement *c1 = new TrackingRectElement(this, "", 0);
48+
c1->setX(100);
49+
c1->setY(100);
50+
t->add(c1);
51+
c1 = new TrackingRectElement(this, "", 1);
52+
c1->setX(100);
53+
c1->setY(1000);
54+
t->add(c1);
55+
c1 = new TrackingRectElement(this, "", 2);
56+
c1->setX(1000);
57+
c1->setY(1000);
58+
t->add(c1);
59+
c1 = new TrackingRectElement(this, "", 3);
60+
c1->setX(1000);
61+
c1->setY(100);
62+
t->add(c1);
4363
m_Model = t;
4464
}
4565

BioTracker/Plugin/BioTrackerPlugin/Controller/ControllerTrackingAlgorithm.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ void ControllerTrackingAlgorithm::connectModelToController()
4646
BioTrackerTrackingAlgorithm *trackingAlg = qobject_cast<BioTrackerTrackingAlgorithm *>(m_Model);
4747
QObject::connect(trackingAlg, &BioTrackerTrackingAlgorithm::emitCvMatA, this, &ControllerTrackingAlgorithm::receiveCvMatFromTrackingAlgorithm);
4848
QObject::connect(trackingAlg, &BioTrackerTrackingAlgorithm::emitTrackingDone, this, &ControllerTrackingAlgorithm::receiveTrackingDone);
49-
5049
}
5150

5251
void ControllerTrackingAlgorithm::receiveCvMatFromTrackingAlgorithm(std::shared_ptr<cv::Mat> mat, QString name)
Lines changed: 91 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,128 @@
11
#include "BioTrackerTrackingAlgorithm.h"
22
#include <future>
33
#include "TrackedComponents\TrackedComponentFactory.h"
4+
#include <chrono>
5+
6+
#include "Model\TrackedComponents\TrackingRectElement.h"
47

58
BioTrackerTrackingAlgorithm::BioTrackerTrackingAlgorithm(IModel *parameter, IModel *trajectory) : _ipp((TrackerParameter*)parameter)
69
{
7-
m_TrackingParameter = (TrackerParameter*)parameter;
8-
m_TrackedTrajectoryMajor = (TrackedTrajectory*)trajectory;
9-
m_frameCount = 0;
10-
_nn2d = new NN2dMapper(m_TrackedTrajectoryMajor);
10+
_TrackingParameter = (TrackerParameter*)parameter;
11+
_TrackedTrajectoryMajor = (TrackedTrajectory*)trajectory;
12+
_nn2d = std::make_shared<NN2dMapper>(_TrackedTrajectoryMajor);
13+
14+
_noFish = _TrackingParameter->getNoFish();
15+
16+
17+
Rectification::instance().initRecitification(80, 80, _TrackedTrajectoryMajor);
18+
Rectification::instance().setupRecitification(100,100,2040,2040);
19+
20+
//TODO: put this into a module
21+
_ofs.open("TrackingOutput.txt", std::ofstream::out);
22+
for (int i = 0; i < _noFish; i++) {
23+
_ofs << "ID,time(ns),x,y,ADeg,ARad,";
24+
}
25+
_ofs << std::endl;
1126
}
27+
/*
28+
BioTrackerTrackingAlgorithm::~BioTrackerTrackingAlgorithm()
29+
{
30+
_ofs.close();
31+
}*/
1232

1333
std::vector<FishPose> BioTrackerTrackingAlgorithm::getLastPositionsAsPose() {
1434
//TODO: This seems kinda fragile: I just assume that the tree has this very certain structure:
1535
// Trajectory -> M Trajectories -> N TrackedElements
1636
// For every of M Trajectories grab the last (highest index) of TrackedElements.
1737
//TODO: If we are tracking somewhere in the middle, this is bad. Do it by id!
1838
std::vector<FishPose> last;
19-
for (int i = 0; i < m_TrackedTrajectoryMajor->numberOfChildrean(); i++) {
20-
TrackedTrajectory *t = (TrackedTrajectory*)m_TrackedTrajectoryMajor->getChild(i);
21-
TrackedElement *e = (TrackedElement *)t->getLastChild();
22-
last.push_back(e->getFishPose());
39+
for (int i = 0; i < _TrackedTrajectoryMajor->numberOfChildrean(); i++) {
40+
TrackedTrajectory *t = dynamic_cast<TrackedTrajectory *>(_TrackedTrajectoryMajor->getChild(i));
41+
if (t) {
42+
TrackedElement *e = (TrackedElement *)t->getLastChild();
43+
last.push_back(e->getFishPose());
44+
}
2345
}
2446
return last;
2547
}
2648

2749
void BioTrackerTrackingAlgorithm::doTracking(std::shared_ptr<cv::Mat> p_image, uint framenumber)
2850
{
29-
_ipp.m_TrackingParameter = m_TrackingParameter;
51+
_ipp.m_TrackingParameter = _TrackingParameter;
52+
auto start = std::chrono::high_resolution_clock::now();
53+
54+
//The user changed the # of fish. Reset the history and start over!
55+
if (_noFish != _TrackingParameter->getNoFish()) {
56+
_noFish = _TrackingParameter->getNoFish();
57+
}
3058

3159
//Do the preprocessing
3260
std::map<std::string, std::shared_ptr<cv::Mat>> images = _ipp.preProcess(p_image);
3361
std::shared_ptr<cv::Mat> dilated = images.find(std::string("Dilated"))->second;
3462
std::shared_ptr<cv::Mat> greyMat = images.find(std::string("Greyscale"))->second;
63+
std::shared_ptr<cv::Mat> sendImage;
3564

3665
//Find blobs via ellipsefitting
37-
_bd.setMaxBlobSize(m_TrackingParameter->getMaxBlobSize());
38-
_bd.setMinBlobSize(m_TrackingParameter->getMinBlobSize());
66+
_bd.setMaxBlobSize(_TrackingParameter->getMaxBlobSize());
67+
_bd.setMinBlobSize(_TrackingParameter->getMinBlobSize());
3968
std::vector<BlobPose> blobs = _bd.getPoses(*dilated, *greyMat);
4069

70+
//This is tricky, as the root node may contain other children than actual trajectories.
71+
//Lets denote trajectories as t (they'll be represented by their currently active child), others with x, the maping goes like this:
72+
// Original: t1 x x t2 x t3 x
73+
// Fishposes for getNewPoses: t1 t2 t3
74+
// Output of getNewPoses: t1' t2' t3'
75+
// Writing them back to the tree: t1'x x t2'x t3'x
76+
// The absence or presence of the x should not matter.
77+
// However, never switch the position of the trajectories. The NN2d mapper relies on this!
78+
// If you mess up the order, add or remove some t, then create a new mapper.
4179
std::vector<FishPose> fish = getLastPositionsAsPose();
80+
81+
//Find new positions using 2D nearest neighbour
4282
std::tuple<std::vector<FishPose>, std::vector<float>> poses = _nn2d->getNewPoses(fish, blobs);
4383

4484
//Insert new poses into data structure
45-
if (std::get<0>(poses).size() == m_TrackedTrajectoryMajor->numberOfChildrean()) { //TODO hardcoded
46-
for (int i = 0; i < m_TrackedTrajectoryMajor->numberOfChildrean(); i++) {
47-
TrackedTrajectory *t = (TrackedTrajectory*)m_TrackedTrajectoryMajor->getChild(i);
48-
TrackedElement *e = new TrackedElement(t, "n.a.", i);
49-
//int x = std::get<0>(poses)[i].position_cm().x;
50-
//int y = std::get<0>(poses)[i].position_cm().y;
51-
e->setFishPose(std::get<0>(poses)[i]);
52-
t->add(e);
85+
//if (std::get<0>(poses).size() == _TrackedTrajectoryMajor->numberOfChildrean()) { //TODO hardcoded
86+
for (int i = 0; i < _TrackedTrajectoryMajor->numberOfChildrean(); i++) {
87+
TrackedTrajectory *t = dynamic_cast<TrackedTrajectory *>(_TrackedTrajectoryMajor->getChild(i));
88+
if (t) {
89+
90+
TrackedElement *e = new TrackedElement(t, "n.a.", i);
91+
e->setFishPose(std::get<0>(poses)[i]);
92+
t->add(e);
93+
94+
_ofs << i << "," << std::chrono::duration_cast<std::chrono::nanoseconds>(start.time_since_epoch()).count()
95+
<< std::get<0>(poses)[i].position_cm().x << "," << std::get<0>(poses)[i].position_cm().y << ","
96+
<< std::get<0>(poses)[i].orientation_deg() << "," << std::get<0>(poses)[i].orientation_rad() << ",";
97+
98+
}
5399
}
54-
}
55-
else {
56-
std::cout << "Error: did not track expected size! Size is: " << std::get<1>(poses).size() << std::endl;
100+
//}
101+
//else {
102+
// std::cout << "Error: did not track expected size! Size is: " << std::get<1>(poses).size() << std::endl;
103+
//}
104+
_ofs << std::endl; //TODO extra module
105+
106+
//Send forth whatever the user selected
107+
switch (_TrackingParameter->getSendImage()) {
108+
case 0: //Send none
109+
break;
110+
case 1:
111+
sendImage = images.find(std::string("Binarized"))->second;
112+
Q_EMIT emitCvMatA(sendImage, QString("Binarized"));
113+
break;
114+
case 2:
115+
sendImage = images.find(std::string("Eroded"))->second;
116+
Q_EMIT emitCvMatA(sendImage, QString("Eroded"));
117+
break;
118+
case 3:
119+
sendImage = images.find(std::string("Dilated"))->second;
120+
Q_EMIT emitCvMatA(sendImage, QString("Dilated"));
121+
break;
122+
case 4:
123+
sendImage = images.find(std::string("Foreground"))->second;
124+
Q_EMIT emitCvMatA(sendImage, QString("Foreground"));
125+
break;
57126
}
58127

59128
//Draw stuff into the output
@@ -64,8 +133,5 @@ void BioTrackerTrackingAlgorithm::doTracking(std::shared_ptr<cv::Mat> p_image, u
64133
}*/
65134

66135

67-
Q_EMIT emitCvMatA(dilated, QString("Processed"));
68-
69-
m_frameCount++;
70136
Q_EMIT emitTrackingDone();
71137
}

BioTracker/Plugin/BioTrackerPlugin/Model/BioTrackerTrackingAlgorithm.h

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,48 +4,47 @@
44

55
#include "Interfaces/IModel/IModel.h"
66

7-
#include "Interfaces/IModel/IModelTrackingAlgorithm.h"
8-
#include "Model/TrackedComponents/TrackedElement.h"
9-
#include "Model/TrackedComponents/TrackedTrajectory.h"
107
#include "TrackerParameter.h"
118

129
#include <opencv2/opencv.hpp>
13-
#include "imageProcessor/detector/blob/cvBlob/BlobsDetector.h"
14-
#include "imageProcessor/preprocessor/ImagePreProcessor.h"
15-
#include "fish/Fish.h"
16-
#include "fish/NN2dMapper.h"
10+
#include "Interfaces/IModel/IModelTrackingAlgorithm.h"
11+
#include "Model/TrackedComponents/TrackedElement.h"
12+
#include "Model/TrackedComponents/TrackedTrajectory.h"
13+
#include "Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.h"
14+
#include "Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h"
15+
#include "Model/TrackingAlgorithm/NN2dMapper.h"
1716

1817

1918
class BioTrackerTrackingAlgorithm : public IModelTrackingAlgorithm
2019
{
2120
Q_OBJECT
22-
public:
21+
public:
2322
BioTrackerTrackingAlgorithm(IModel* parameter, IModel* trajectory/*QObject *parent = 0, ITrackedComponentFactory *factory = 0*/);
2423

2524
Q_SIGNALS:
2625
void emitCvMatA(std::shared_ptr<cv::Mat> image, QString name);
2726

2827
// ITrackingAlgorithm interface
29-
public Q_SLOTS:
30-
void doTracking(std::shared_ptr<cv::Mat> image, uint framenumber) override;
31-
28+
public Q_SLOTS:
29+
void doTracking(std::shared_ptr<cv::Mat> image, uint framenumber) override;
3230

3331
private:
3432
std::vector<FishPose> getLastPositionsAsPose();
3533

36-
TrackedTrajectory *m_TrackedTrajectoryMajor;
34+
TrackedTrajectory* _TrackedTrajectoryMajor;
3735

38-
TrackerParameter* m_TrackingParameter;
36+
TrackerParameter* _TrackingParameter;
3937

4038
ImagePreProcessor _ipp;
4139
BlobsDetector _bd;
42-
std::vector<Fish> m_fishList;
43-
NN2dMapper *_nn2d;
44-
45-
int m_frameCount;
40+
std::shared_ptr<NN2dMapper> _nn2d;
4641

4742
// background subtraction
4843
cv::Ptr<cv::BackgroundSubtractorMOG2> _pMOG;
44+
45+
int _noFish;
46+
47+
std::ofstream _ofs;
4948
};
5049

5150
#endif // BIOTRACKERTRACKINGALGORITHM_H

BioTracker/Plugin/BioTrackerPlugin/Model/TrackedComponents/TrackedElement.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "QGraphicsItem"
55
#include "Interfaces/IModel/IModelTrackedComponent.h"
66
#include "QString"
7-
#include "fish\pose\FishPose.h"
7+
#include "Model\TrackedComponents\pose\FishPose.h"
88

99
/**
1010
* This class is an example of how a TrackedComponent could be defined.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "TrackingRectElement.h"
2+
3+
4+
void TrackingRectElement::pressed()
5+
{
6+
_pressed = true;
7+
Q_EMIT notifyView();
8+
9+
}
10+
11+
void TrackingRectElement::notPressed()
12+
{
13+
_pressed = false;
14+
Q_EMIT notifyView();
15+
}
16+

0 commit comments

Comments
 (0)