Skip to content

Commit eaecc31

Browse files
committed
deepsort v1.2
1 parent a42baaa commit eaecc31

File tree

12 files changed

+1657
-53
lines changed

12 files changed

+1657
-53
lines changed

CMakeLists.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ find_package(OpenCV 4 REQUIRED )
1919
include_directories(
2020
${OpenCV_INCLUDE_DIRS}/include
2121
${CMAKE_SOURCE_DIR}/tracker/deepsort/include
22-
${CMAKE_SOURCE_DIR}/detector/YOLOv5/include
22+
${CMAKE_SOURCE_DIR}/tracker/bytetrack/include
23+
${CMAKE_SOURCE_DIR}/detector/YOLOv5/include
2324

2425
)
2526

2627

2728
add_executable(DeepSORT
2829
detector/YOLOv5/src/YOLOv5Detector.cpp
30+
2931
tracker/deepsort/src/FeatureTensor.cpp
3032
tracker/deepsort/src/model.cpp
3133
tracker/deepsort/src/kalmanfilter.cpp
@@ -36,5 +38,12 @@ add_executable(DeepSORT
3638
tracker/deepsort/src/munkres.cpp
3739
tracker/deepsort/src/hungarianoper.cpp
3840

41+
tracker/bytetrack/src/BytekalmanFilter.cpp
42+
tracker/bytetrack/src/BYTETracker.cpp
43+
tracker/bytetrack/src/lapjv.cpp
44+
tracker/bytetrack/src/STrack.cpp
45+
tracker/bytetrack/src/utils.cpp
46+
47+
3948
main.cpp)
4049
target_link_libraries(DeepSORT PRIVATE "${ONNXRUNTIME_DIR}/lib/libonnxruntime.so" ${OpenCV_LIBS} Eigen3::Eigen)

README.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,42 @@
11
# DeepSORT
22

3-
MOT using deepsort yolo5 with C++
3+
# MOT(Multi-object tracking) using yolov5 with C++ support deepsort and bytetrack
44

5-
# 多目标跟踪论文 DeepSORT 实现
65

76
flyfish
87

98
## 前言
10-
代码采用C++实现,支持YOLOv5 6.x。
9+
代码采用C++实现,目标检测支持YOLOv5 6.x,跟踪支持deepsort and bytetrack
1110
检测模型可以直接从YOLOv5官网,导出onnx使用
1211
特征提取可以自己训练,导出onnx使用,onnxruntime cpu 推理,方便使用.
1312
特征支持自定义维度例如 128,256,512等
1413

15-
原论文地址
14+
本文源码地址
1615

1716
```c
18-
https://arxiv.org/pdf/1703.07402.pdf
17+
https://github.com/shaoshengsong/DeepSORT
1918
```
2019

21-
本文源码地址
20+
## deepsort v1.12
21+
新增bytetrack跟踪
2222

23+
bytetrack论文
2324
```c
24-
https://github.com/shaoshengsong/DeepSORT
25+
http://arxiv.org/abs/2110.06864
26+
```
27+
28+
bytetrack代码
29+
```c
30+
https://github.com/ifzhang/ByteTrack
2531
```
2632

2733
## deepsort v1.1
34+
deepsort原论文地址
35+
36+
```c
37+
https://arxiv.org/pdf/1703.07402.pdf
38+
```
39+
2840

2941
```c
3042
MOT using deepsort yolo5 with C++

main.cpp

Lines changed: 87 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
#include "YOLOv5Detector.h"
1212

1313
#include "FeatureTensor.h"
14-
#include "tracker.h"
14+
#include "BYTETracker.h" //bytetrack
15+
#include "tracker.h"//deepsort
1516
//Deep SORT parameter
1617

1718
const int nn_budget=100;
@@ -27,12 +28,94 @@ void get_detections(DETECTBOX box,float confidence,DETECTIONS& d)
2728
}
2829

2930

31+
void test_deepsort(cv::Mat& frame, std::vector<detect_result>& results,tracker& mytracker)
32+
{
33+
std::vector<detect_result> objects;
34+
35+
DETECTIONS detections;
36+
for (detect_result dr : results)
37+
{
38+
//cv::putText(frame, classes[dr.classId], cv::Point(dr.box.tl().x+10, dr.box.tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .8, cv::Scalar(0, 255, 0));
39+
if(dr.classId == 0) //person
40+
{
41+
objects.push_back(dr);
42+
cv::rectangle(frame, dr.box, cv::Scalar(255, 0, 0), 2);
43+
get_detections(DETECTBOX(dr.box.x, dr.box.y,dr.box.width, dr.box.height),dr.confidence, detections);
44+
}
45+
}
3046

47+
std::cout<<"begin track"<<std::endl;
48+
if(FeatureTensor::getInstance()->getRectsFeature(frame, detections))
49+
{
50+
std::cout << "get feature succeed!"<<std::endl;
51+
mytracker.predict();
52+
mytracker.update(detections);
53+
std::vector<RESULT_DATA> result;
54+
for(Track& track : mytracker.tracks) {
55+
if(!track.is_confirmed() || track.time_since_update > 1) continue;
56+
result.push_back(std::make_pair(track.track_id, track.to_tlwh()));
57+
}
58+
for(unsigned int k = 0; k < detections.size(); k++)
59+
{
60+
DETECTBOX tmpbox = detections[k].tlwh;
61+
cv::Rect rect(tmpbox(0), tmpbox(1), tmpbox(2), tmpbox(3));
62+
cv::rectangle(frame, rect, cv::Scalar(0,0,255), 4);
63+
// cvScalar的储存顺序是B-G-R,CV_RGB的储存顺序是R-G-B
3164

65+
for(unsigned int k = 0; k < result.size(); k++)
66+
{
67+
DETECTBOX tmp = result[k].second;
68+
cv::Rect rect = cv::Rect(tmp(0), tmp(1), tmp(2), tmp(3));
69+
rectangle(frame, rect, cv::Scalar(255, 255, 0), 2);
70+
71+
std::string label = cv::format("%d", result[k].first);
72+
cv::putText(frame, label, cv::Point(rect.x, rect.y), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255, 255, 0), 2);
73+
}
74+
}
75+
}
76+
std::cout<<"end track"<<std::endl;
77+
}
78+
79+
80+
void test_bytetrack(cv::Mat& frame, std::vector<detect_result>& results,BYTETracker& tracker)
81+
{
82+
std::vector<detect_result> objects;
83+
84+
85+
for (detect_result dr : results)
86+
{
87+
88+
if(dr.classId == 0) //person
89+
{
90+
objects.push_back(dr);
91+
}
92+
}
93+
94+
95+
std::vector<STrack> output_stracks = tracker.update(objects);
96+
97+
for (unsigned long i = 0; i < output_stracks.size(); i++)
98+
{
99+
std::vector<float> tlwh = output_stracks[i].tlwh;
100+
bool vertical = tlwh[2] / tlwh[3] > 1.6;
101+
if (tlwh[2] * tlwh[3] > 20 && !vertical)
102+
{
103+
cv::Scalar s = tracker.get_color(output_stracks[i].track_id);
104+
cv::putText(frame, cv::format("%d", output_stracks[i].track_id), cv::Point(tlwh[0], tlwh[1] - 5),
105+
0, 0.6, cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
106+
cv::rectangle(frame, cv::Rect(tlwh[0], tlwh[1], tlwh[2], tlwh[3]), s, 2);
107+
}
108+
}
109+
110+
111+
}
32112
int main(int argc, char *argv[])
33113
{
34-
//deep SORT
114+
//deepsort
35115
tracker mytracker(max_cosine_distance, nn_budget);
116+
//bytetrack
117+
int fps=20;
118+
BYTETracker bytetracker(fps, 30);
36119
//-----------------------------------------------------------------------
37120
// 加载类别名称
38121
std::vector<std::string> classes;
@@ -85,50 +168,9 @@ int main(int argc, char *argv[])
85168
auto detect_time =std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();//ms
86169
std::cout<<classes.size()<<":"<<results.size()<<":"<<num_frames<<std::endl;
87170

88-
std::vector<detect_result> objects;
89-
90-
DETECTIONS detections;
91-
for (detect_result dr : results)
92-
{
93-
//cv::putText(frame, classes[dr.classId], cv::Point(dr.box.tl().x+10, dr.box.tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .8, cv::Scalar(0, 255, 0));
94-
if(dr.classId == 0) //person
95-
{
96-
objects.push_back(dr);
97-
cv::rectangle(frame, dr.box, cv::Scalar(255, 0, 0), 2);
98-
get_detections(DETECTBOX(dr.box.x, dr.box.y,dr.box.width, dr.box.height),dr.confidence, detections);
99-
}
100-
}
101171

102-
std::cout<<"begin track"<<std::endl;
103-
if(FeatureTensor::getInstance()->getRectsFeature(frame, detections))
104-
{
105-
std::cout << "get feature succeed!"<<std::endl;
106-
mytracker.predict();
107-
mytracker.update(detections);
108-
std::vector<RESULT_DATA> result;
109-
for(Track& track : mytracker.tracks) {
110-
if(!track.is_confirmed() || track.time_since_update > 1) continue;
111-
result.push_back(std::make_pair(track.track_id, track.to_tlwh()));
112-
}
113-
for(unsigned int k = 0; k < detections.size(); k++)
114-
{
115-
DETECTBOX tmpbox = detections[k].tlwh;
116-
cv::Rect rect(tmpbox(0), tmpbox(1), tmpbox(2), tmpbox(3));
117-
cv::rectangle(frame, rect, cv::Scalar(0,0,255), 4);
118-
// cvScalar的储存顺序是B-G-R,CV_RGB的储存顺序是R-G-B
119-
120-
for(unsigned int k = 0; k < result.size(); k++)
121-
{
122-
DETECTBOX tmp = result[k].second;
123-
cv::Rect rect = cv::Rect(tmp(0), tmp(1), tmp(2), tmp(3));
124-
rectangle(frame, rect, cv::Scalar(255, 255, 0), 2);
125-
126-
std::string label = cv::format("%d", result[k].first);
127-
cv::putText(frame, label, cv::Point(rect.x, rect.y), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255, 255, 0), 2);
128-
}
129-
}
130-
}
131-
std::cout<<"end track"<<std::endl;
172+
//test_deepsort(frame, results,mytracker);
173+
test_bytetrack(frame, results,bytetracker);
132174

133175
cv::imshow("YOLOv5-6.x", frame);
134176

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
#include "STrack.h"
4+
#include "YOLOv5Detector.h"
5+
6+
7+
class BYTETracker
8+
{
9+
public:
10+
BYTETracker(int frame_rate = 30, int track_buffer = 30);
11+
~BYTETracker();
12+
13+
std::vector<STrack> update(const std::vector<detect_result>& objects);
14+
cv::Scalar get_color(int idx);
15+
16+
private:
17+
std::vector<STrack*> joint_stracks( std::vector<STrack*> &tlista, std::vector<STrack> &tlistb);
18+
std::vector<STrack> joint_stracks( std::vector<STrack> &tlista, std::vector<STrack> &tlistb);
19+
20+
std::vector<STrack> sub_stracks( std::vector<STrack> &tlista, std::vector<STrack> &tlistb);
21+
void remove_duplicate_stracks( std::vector<STrack> &resa, std::vector<STrack> &resb, std::vector<STrack> &stracksa, std::vector<STrack> &stracksb);
22+
23+
void linear_assignment( std::vector< std::vector<float> > &cost_matrix, int cost_matrix_size, int cost_matrix_size_size, float thresh,
24+
std::vector< std::vector<int> > &matches, std::vector<int> &unmatched_a, std::vector<int> &unmatched_b);
25+
std::vector< std::vector<float> > iou_distance( std::vector<STrack*> &atracks, std::vector<STrack> &btracks, int &dist_size, int &dist_size_size);
26+
std::vector< std::vector<float> > iou_distance( std::vector<STrack> &atracks, std::vector<STrack> &btracks);
27+
std::vector< std::vector<float> > ious( std::vector< std::vector<float> > &atlbrs, std::vector< std::vector<float> > &btlbrs);
28+
29+
double lapjv(const std::vector< std::vector<float> > &cost, std::vector<int> &rowsol, std::vector<int> &colsol,
30+
bool extend_cost = false, float cost_limit = LONG_MAX, bool return_cost = true);
31+
32+
private:
33+
34+
float track_thresh;
35+
float high_thresh;
36+
float match_thresh;
37+
int frame_id;
38+
int max_time_lost;
39+
40+
std::vector<STrack> tracked_stracks;
41+
std::vector<STrack> lost_stracks;
42+
std::vector<STrack> removed_stracks;
43+
byte_kalman::ByteKalmanFilter kalman_filter;
44+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include "dataType.h"
4+
5+
namespace byte_kalman
6+
{
7+
class ByteKalmanFilter
8+
{
9+
public:
10+
static const double chi2inv95[10];
11+
ByteKalmanFilter();
12+
KAL_DATA initiate(const DETECTBOX& measurement);
13+
void predict(KAL_MEAN& mean, KAL_COVA& covariance);
14+
KAL_HDATA project(const KAL_MEAN& mean, const KAL_COVA& covariance);
15+
KAL_DATA update(const KAL_MEAN& mean,
16+
const KAL_COVA& covariance,
17+
const DETECTBOX& measurement);
18+
19+
Eigen::Matrix<float, 1, -1> gating_distance(
20+
const KAL_MEAN& mean,
21+
const KAL_COVA& covariance,
22+
const std::vector<DETECTBOX>& measurements,
23+
bool only_position = false);
24+
25+
private:
26+
Eigen::Matrix<float, 8, 8, Eigen::RowMajor> _motion_mat;
27+
Eigen::Matrix<float, 4, 8, Eigen::RowMajor> _update_mat;
28+
float _std_weight_position;
29+
float _std_weight_velocity;
30+
};
31+
}

tracker/bytetrack/include/STrack.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#pragma once
2+
3+
#include <opencv2/opencv.hpp>
4+
#include "BytekalmanFilter.h"
5+
6+
enum TrackState { New = 0, Tracked, Lost, Removed };
7+
8+
class STrack
9+
{
10+
public:
11+
STrack( std::vector<float> tlwh_, float score);
12+
~STrack();
13+
14+
std::vector<float> static tlbr_to_tlwh( std::vector<float> &tlbr);
15+
void static multi_predict( std::vector<STrack*> &stracks, byte_kalman::ByteKalmanFilter &kalman_filter);
16+
void static_tlwh();
17+
void static_tlbr();
18+
std::vector<float> tlwh_to_xyah( std::vector<float> tlwh_tmp);
19+
std::vector<float> to_xyah();
20+
void mark_lost();
21+
void mark_removed();
22+
int next_id();
23+
int end_frame();
24+
25+
void activate(byte_kalman::ByteKalmanFilter &kalman_filter, int frame_id);
26+
void re_activate(STrack &new_track, int frame_id, bool new_id = false);
27+
void update(STrack &new_track, int frame_id);
28+
29+
public:
30+
bool is_activated;
31+
int track_id;
32+
int state;
33+
34+
std::vector<float> _tlwh;
35+
std::vector<float> tlwh;
36+
std::vector<float> tlbr;
37+
int frame_id;
38+
int tracklet_len;
39+
int start_frame;
40+
41+
KAL_MEAN mean;
42+
KAL_COVA covariance;
43+
float score;
44+
45+
private:
46+
byte_kalman::ByteKalmanFilter kalman_filter;
47+
};

0 commit comments

Comments
 (0)