4
votes

Good day,

I have use YOLOv3 model to detect only human objects appear in the scene. Basically, YOLO model tries to detect human objects in each frame, although it seems like tracking since the bounding box is constantly moves.

I am looking for a feasible method to track each detected human objects by assigning an identifier to each of them. (Please see provided image)

Following codes are used to draw a bounding box based on left, top, right, bottom, which imply x, width, y, height. Is that possible for me to assign an identifier to each detected human objects?

E.g. Assign ID_1 to detected "person:0.73", while assign ID_2 to "person:1.00"

Much appreciate your help and time, thank you.

Trying to assign an identifier to each detected person

Trying to assign an identifier to each detected person

def drawPred(classId, conf, left, top, right, bottom):
    # Draw a bounding box.
    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)

1
For tracking you can use Kalman Filter as in here. He performs detection after each 10 frames and uses tracking in between which doesn't work as well as detection at each frame.Hadi GhahremanNezhad
Use sort tracker: github.com/abewley/sortNuzhny

1 Answers

2
votes

If C++ implementation is okay, You probably want to use this popular github repository https://github.com/AlexeyAB/darknet

If you read the documentation, it has C++ API which you can use darknet as library (so you can use your yolo model) and load it to your C++ program. Take a look at C++ program example that use darknet library here https://github.com/AlexeyAB/darknet/blob/master/src/yolo_console_dll.cpp .

In that C++ code, the author gives 3 option to do object tracking :

  1. Track Optical Flow algorithm, but it only works for live detection, not for video. You can use the algorithm by uncomment this line //#define TRACK_OPTFLOW . Take a look at line 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
  1. Kalman Filter, not really recommended because it's not really accurate, but might work for CCTV or stationary camera. To use kalman filter change this value to true bool const use_kalman_filter = false;. Take a look at line 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();
                            }
                        }
  1. Custom Object Tracker, I used this custom function and it performs better than kalman filter in my case, it will give you track ID for each object.
// 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);
                        }