basic版本的yolo,在yolov3版本上增加人体跟踪
xuepengqiang
2020-05-26 5966f2b095841627d62daac0159e81f83544b85c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
//
// Created by Scheaven on 2020/3/23.
//
 
#include "tracker_manager.h"
#include <thread>
#include <unistd.h>
#include <cstdlib>
 
 
TrackerManager::TrackerManager()
{
    cout << "---------loading detect ---------"  <<  endl;
}
 
TrackerManager::~TrackerManager()
{
 
}
 
//调用其他释放函数
void TrackerManager::release()
{
    DetecterManager::getInstance()->release();
    FeatureEncoder::getInstance()->release();
}
 
void TrackerManager::init_load_model()
{
    cout << "loading YOLO model ---------"  <<  endl;
    DetecterManager::getInstance();
    Detector::getInstance();
    FeatureEncoder::getInstance();
}
 
//添加待追踪摄像头
bool TrackerManager::add_cam(int cam_id){
    if (cam_id==(this->CAMERAS_VCT.size()+1))
    {
        auto cam_tracker = std::make_shared<tracker>(max_cosine_distance, nn_budget);
        this->CAMERAS_VCT.push_back(cam_tracker);
        return true;
    }else if(cam_id<this->CAMERAS_VCT.size())
    {
        cout << "-- The camera ID is occupied!"  <<  endl;
        return false;
    }else
    {
        cout << "-- Camera ID discontinuous!"  <<  endl;
        return false;
    }
}
 
// ------------------------------ SDK 代码封装部分 ----------------------------------
// 模型检测 + 编码器 + 追踪 SDK封装
void TrackerManager::single_SDK(const int cam_id, const void *img, TResult *t_result)
{
    TImage *frame_img = (TImage*)img;
    cv::Mat frame(Size(frame_img->width, frame_img->height), CV_8UC3);
    frame.data = (uchar*)frame_img->data;
    DETECTIONS detections;
    DetecterManager::getInstance()->detecter_main(frame, detections);
    if(detections.size()>0)
    {
        if(FeatureEncoder::getInstance()->getRectsFeature(frame , detections) == false)
        {
            std::cout<< " encoder code failed ----" << std::endl;
        }
        single_tracker(cam_id, detections);
        switch_SDK_TResult(cam_id, frame, detections, t_result);
 
    }
 
}
 
// 转换成SDK 想要的结果
void TrackerManager::switch_SDK_TResult(int cam_id, cv::Mat img, DETECTIONS detections, TResult *t_result)
{
    t_result->targets = (Target*)malloc(sizeof(Target) * this->CAMERAS_VCT[cam_id]->tracks.size());
    int w_count = 0;
    for(auto& track :this->CAMERAS_VCT[cam_id]->tracks)
    {
        Target target;
        init_target(&target);
        RESULT_STRUCT result;
        if(!track->is_confirmed() || track->time_since_update > 1) continue;
        
 
        if(detections.size() <= w_count){ // 极个别无法没有confidence的问题
            break;
        }else{
            DETECTBOX tmpbox = detections[w_count].tlwh; // 检测的框信息
            target.rect.left = tmpbox(0);
            target.rect.top =  tmpbox(1);
            target.rect.right = tmpbox(0) + tmpbox(2);
            target.rect.bottom = tmpbox(1) + tmpbox(3);
            target.id = track->track_id;
            target.confidence = detections[w_count].confidence*100;
        }
 
        t_result->targets[w_count] = target;
        w_count ++;
    }
    t_result->count = w_count;
}
 
// ------------------------------单目多线程摄像头追踪代码部分 ----------------------------
// 模型检测 + 编码器 + 追踪
 void TrackerManager::single_detect_tracking(int cam_id, cv::Mat frame, FRAME_RESULT result_vec)
{
    DETECTIONS detections;
    DetecterManager::getInstance()->detecter_main(frame, detections);
 
    if(FeatureEncoder::getInstance()->getRectsFeature(frame , detections) == false)
    {
        std::cout<< " encoder code failed ----" << std::endl;
    }
    single_tracker(cam_id, detections); //單目追踪
}
 
//一次性追踪多摄像头(添加的摄像头列表全部追踪)信息
void TrackerManager::mul_detect_tracking(std::vector<int> cam_ids, std::vector<cv::Mat> frame_vec, std::vector<FRAME_RESULT>&  results_vec) // 多摄像头追踪
{
 
    std::vector<std::thread> thread_vec;
    for (int i = 0; i < cam_ids.size(); ++i)
    {
        std::thread tracking_thread(&TrackerManager::single_detect_tracking, this,cam_ids[i], frame_vec[i], results_vec[i]);
        thread_vec.emplace_back(std::move(tracking_thread));
    }
 
    for (auto &sub_thread : thread_vec)
    {
        sub_thread.join();
    }
 
 
    for (int i = 0; i < cam_ids.size(); ++i)
    {
        single_draw(cam_ids[i], frame_vec[i], results_vec[i]); //绘制结果信息(展示图像)
    }
 
}
 
 
// 编码器 + 追踪
void TrackerManager::sub_thread_tracking(int cam_id, cv::Mat frame, FRAME_RESULT result_vec, DETECTIONS detections)
{
    std::clock_t t_strat2 = std::clock();
    if(FeatureEncoder::getInstance()->getRectsFeature(frame , detections) == false)
    {
        std::cout<< " encoder code failed ----" << std::endl;
    }
    std::clock_t t_strat3 = std::clock();
    single_tracker(cam_id, detections); //單目追踪
    std::clock_t t_strat4 = std::clock();
}
 
void TrackerManager::single_tracker(int cam_id, DETECTIONS& detections)
{
    auto cam_tracker = this->CAMERAS_VCT[cam_id];
 
    cam_tracker->predict();
    cam_tracker->update(detections);
 
    this->CAMERAS_VCT[cam_id] = cam_tracker;
}
 
void TrackerManager::single_draw(int cam_id, cv::Mat img, FRAME_RESULT& result_vec)
{
    for(auto& track : this->CAMERAS_VCT[cam_id]->tracks)
    {
        RESULT_STRUCT result;
        if(!track->is_confirmed() || track->time_since_update > 1) continue;
        DETECTBOX tmpbox = track->to_tlwh();
        result.rect = cv::Rect(tmpbox(0),tmpbox(1),tmpbox(2),tmpbox(3));
        result.human_id = track->track_id;
//        result.confidence = detection.confidence;
        result_vec.push_back(result);
    }
 
    draw_result(img, result_vec);
}
 
 
 
std::vector<DETECTION_ROW> TrackerManager::deal_features(std::vector<cv::Rect> boxes, std::vector<vector<float> > feats_vec)
{
    DETECTIONS detections;
    for (int i = 0; i < boxes.size(); ++i)
    {
        DETECTION_ROW tmpRow;
 
        tmpRow.tlwh = DETECTBOX(boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);//DETECTBOX(x, y, w, h);
        tmpRow.confidence = 1;
 
        for(int j = 0; j < 128; j++)
        {
            tmpRow.feature[j] = feats_vec[i][j];
        }
        cout << tmpRow.tlwh << endl;
        cout << tmpRow.feature << endl;
        detections.push_back(tmpRow);
//        std::cout<<"Detections Size:::::"<<detections.size() <<std::endl;
    }
    return detections;
}
 
Mat TrackerManager:: h_tracker(int cam_id, Mat frame, DETECTIONS detections){
    auto cam_tracker = this->CAMERAS_VCT[cam_id];
 
    cam_tracker->predict();
    cam_tracker->update(detections);
    std::vector<RESULT_DATA> result;
//    std::cout << " tracks Size:::::" << cam_tracker->tracks.size() << std::endl;
 
    for(auto& track : cam_tracker->tracks) {
        if(track->is_confirmed() && track->time_since_update > 1) continue;
        result.push_back(std::make_pair(track->track_id, track->to_tlwh()));
 
 
        DETECTBOX tmpbox = track->to_tlwh();
        cv::Rect rect(tmpbox(0), tmpbox(1), tmpbox(2), tmpbox(3));
        cv::rectangle(frame, rect, cv::Scalar(0,0,255), 4);
        std::string label = to_string(track->track_id);
        cv::putText(frame, label, cv::Point(rect.x, rect.y), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255, 0, 0), 2);
    }
 
    this->CAMERAS_VCT[cam_id] = cam_tracker;
 
    return frame;
}
 
 
void TrackerManager::init_target(Target *t){
    t->attribute = NULL;
    t->feature = NULL;
    t->id = 0;
    t->rect = TRect{0,0,0,0};
    t->confidence = 0;
}