如何跟踪 YOLOv3 产生的输出?

Posted

技术标签:

【中文标题】如何跟踪 YOLOv3 产生的输出?【英文标题】:How to track output produced by YOLOv3? 【发布时间】:2019-11-09 21:09:45 【问题描述】:

早安,

我使用 YOLOv3 模型来检测场景中仅出现人类对象。基本上,YOLO 模型尝试在每一帧中检测人体对象,尽管它看起来像是在跟踪,因为边界框是不断移动的。

我正在寻找一种可行的方法来跟踪每个检测到的人体对象,方法是为每个对象分配一个标识符。 (请参阅提供的图片)

以下代码用于绘制基于left、top、right、bottom的边界框,这意味着x、width、y、height。我可以为每个检测到的人体对象分配一个标识符吗?

例如将 ID_1 分配给检测到的“person:0.73”,将 ID_2 分配给“person:1.00”

非常感谢您的帮助和时间,谢谢。

尝试为每个检测到的人分配一个标识符

def drawPred(classId, conf, left, top, right, bottom):
    # 画一个边界框。
    cv2.rectangle(resized_frame, (left, top), (right, bottom), (255,0,255), 5)

label = '%.2f' % conf

# Get the label for the class name and its confidence
if classes:
    assert(classId < len(classes))
    label = '%s:%s' % (classes[classId], label)

#Display the label at the top of the bounding box
labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
top = max(top, labelSize[1]) - 5
cv2.putText(resized_frame, label, (left, top), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,255), 2)

【问题讨论】:

对于跟踪,您可以使用卡尔曼滤波器,如 here。他在每 10 帧后执行检测,并在其间使用跟踪,这与每帧的检测效果一样好。 使用排序跟踪器:github.com/abewley/sort 【参考方案1】:

如果 C++ 实现没问题,你可能想使用这个流行的 github 存储库https://github.com/AlexeyAB/darknet

如果您阅读文档,它有 C++ API,您可以使用 darknet 作为库(因此您可以使用您的 yolo 模型)并将其加载到您的 C++ 程序中。在https://github.com/AlexeyAB/darknet/blob/master/src/yolo_console_dll.cpp 处查看使用暗网库的 C++ 程序示例。

在那个 C++ 代码中,作者提供了 3 个选项来进行对象跟踪:

    跟踪光流算法,但它只适用于实时检测,不适用于视频。您可以通过取消注释此行 //#define TRACK_OPTFLOW 来使用该算法。看看508~522行
#ifdef TRACK_OPTFLOW
                        if (detection_data.new_detection) 
                            tracker_flow.update_tracking_flow(detection_data.cap_frame, detection_data.result_vec);
                            while (track_optflow_queue.size() > 0) 
                                draw_frame = track_optflow_queue.back();
                                result_vec = tracker_flow.tracking_flow(track_optflow_queue.front(), false);
                                track_optflow_queue.pop();
                            
                        
                        else 
                            track_optflow_queue.push(cap_frame);
                            result_vec = tracker_flow.tracking_flow(cap_frame, false);
                        
                        detection_data.new_detection = true;    // to correct kalman filter
#endif //TRACK_OPTFLOW
    卡尔曼滤波器,不太推荐,因为它不是很准确,但可能适用于闭路电视或固定摄像机。要使用卡尔曼滤波器,请将此值更改为 true bool const use_kalman_filter = false;。看看524~532行
// track ID by using kalman filter
                        if (use_kalman_filter) 
                            if (detection_data.new_detection) 
                                result_vec = track_kalman.correct(result_vec);
                            
                            else 
                                result_vec = track_kalman.predict();
                            
                        
    自定义对象跟踪器,我使用了这个自定义函数,在我的例子中它比卡尔曼滤波器执行得更好,它会为您提供每个对象的跟踪 ID。
// track ID by using custom function
                        else 
                            int frame_story = std::max(5, current_fps_cap.load());
                            result_vec = detector.tracking_id(result_vec, true, frame_story, 40);
                        

【讨论】:

您的自定义跟踪器是什么? @HadiGhahremanNezhad Alexey 在他的 repo 中提供了算法

以上是关于如何跟踪 YOLOv3 产生的输出?的主要内容,如果未能解决你的问题,请参考以下文章

如何入门yolo目标检测?

yolov3 darknet 转 TVM 推理输出一文读懂

Yolo v3 模型输出澄清与 keras

strace

如何解释 Xdebug 计算机化跟踪输出?

调试时如何在 Visual C++ 2010 中跟踪/输出时间戳