Skip to main content

Multi object tracking

Project description

Multi object tracking class

Perform multi object tracking and use a custom function for tracked objects

MOT arguments:

  • mot_cfg - configuration dictionary for MOT (tamplate below)
mot_cfg = {
    'od_classes':'SPECIFY',       # Object detection algorithm classes path
    'od_algo':'yolo',
    'od_wpath':'SPECIFY',         # Object detection algorithm weights path
    'od_cpath':'SPECIFY',         # Object detection algorithm config path
    'od_nms_thr':0.4,
    'od_conf_thr':0.5,
    'od_img_size':416,
    'od_cuda':True,
    't_classes':'SPECIFY',        # List of classes to track
    't_algo':'deepsort',
    't_cuda':True,
    't_metric':'cosine',
    't_max_cosine_distance':0.2,
    't_budget':100,
    't_max_iou_distance':0.7,
    't_max_age':70,
    't_n_init':3
}

MOT methods:

  • detect_objects - detect object from a frame
  • track_objects - perform a tracking update on frame

Algorithms

Currently available object detection algorithms:

  • YOLOv3
  • YOLOv4

Currently available tracking algorithms:

  • DeepSORT

Installation

To use the package torch, torchvision and opencv must be also installed.

Note: It is recommended to use opencv compiled with CUDA support, because algorithms that use opencv's darknet backend like YOLOv3/v4 run an order of magnitude faster on a GPU.

pip install pymot

Usage

Without a custom function for tracked objects
from pymot.mot import MOT
import cv2

mot_tracker = MOT(mot_cfg)

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    if cv2.waitKey(1) & 0xFF == ord("q"):
        cap.release()
        cv2.destroyAllWindows()
        break

    tracked_ojb_info, frame_with_bboxes, _ = mot_tracker.track_objects(frame)

    cv2.imshow('Object tracking with deepSORT', frame_with_bboxes)
With a custom function for tracked objects
from pymot.mot import MOT
import cv2

mot_tracker = MOT(mot_cfg)

cap = cv2.VideoCapture(0)


def custom_processing_function(
        frame, 
        tracking_id, 
        obj_coord, 
        **proc_kwargs
    ) -> tuple[tuple, tuple]:
    xmin, ymin, xmax, ymax = obj_coord

    # If number of processed objects is more than max limit,
    # delete the first to enter.
    if len(proc_kwargs['proc_obj_info'])>proc_kwargs['max_n_obj']:
        if proc_kwargs['last_obj_to_del'] not in proc_kwargs['proc_obj_info']:
            proc_kwargs['last_obj_to_del'] += 1
        else:
            del proc_kwargs['proc_obj_info'][proc_kwargs['last_obj_to_del']]

    # If there are no processed objects set the first to enter id
    # as last_obj_to_del.
    if len(proc_kwargs['proc_obj_info']) == 0:
        proc_kwargs['last_obj_to_del'] = tracking_id

    # If new tracking id, create new entry in the processed objects dict.
    if tracking_id>proc_kwargs['prev_id']:
        proc_kwargs['prev_id'] = tracking_id
        proc_kwargs['proc_obj_info'][tracking_id] = [1, [], [], False]
        # Processing object information dict list element meaning:
        # 0 - counter,
        # 1 - custom intermediate data accumulated until final processing,
        # 2 - data assigned after final processing,
        # 3 - if object has 2 states, e.g. recognized, unrecognized

    # If the number of performed processings on a object with a certain
    # tracking id is less than needed, do another processing.
    if proc_kwargs['proc_obj_info'][tracking_id][0]<=proc_kwargs['n_det']:

        # DO SOMETHING

        proc_kwargs['proc_obj_info'][tracking_id][1].append(plate_number)

        idx = int(proc_kwargs['proc_obj_info'][tracking_id][0] \
            * (len(proc_kwargs['proc_animation']) / proc_kwargs['n_det']))

        proc_kwargs['proc_obj_info'][tracking_id][2] \
            = proc_kwargs['proc_animation'][idx - 1 \
                if idx==len(proc_kwargs['proc_animation']) else idx]

        proc_kwargs['proc_obj_info'][tracking_id][0] += 1

    # If the number of performed processings on a object with a certain
    # tracking id has sufficed do final processing.
    if proc_kwargs['proc_obj_info'][tracking_id][0]==proc_kwargs['n_det']+1:

        # DO SOMETHING

        proc_kwargs['proc_obj_info'][tracking_id][0] += 1

    output = (
        (
            proc_kwargs['proc_obj_info'], 
            proc_kwargs['last_obj_to_del'], 
            proc_kwargs['prev_id']
        ),
        (
            False, 
            proc_kwargs['proc_obj_info'][tracking_id][3],
            ((0,255,0),(0,0,255)),
            proc_kwargs['proc_obj_info'][tracking_id][2]
        )
    )

    return output


prev_id = -1
n_det = 10
max_n_obj = 50
last_obj_to_del = 0
proc_obj_info = {}
proc_animation = {i:'|'*(i+1) for i in range(8)}

while True:
    ret, frame = cap.read()
    if not ret:
        break

    if cv2.waitKey(1) & 0xFF == ord("q"):
        cap.release()
        cv2.destroyAllWindows()
        break

    output = mot_tracker.track_objects(
        frame,
        custom_processing_function,
        prev_id=prev_id,
        n_det=n_det,
        max_n_obj=max_n_obj,
        last_obj_to_del=last_obj_to_del,
        proc_animation=proc_animation,
        # Custom kwargs
    )

    tracked_ojb_info, frame_with_bboxes, proc_obj_info_tuple = output

    if None not in proc_obj_info_tuple:
        proc_obj_info, last_obj_to_del, prev_id = proc_obj_info_tuple

    cv2.imshow('Object tracking with deepSORT', frame_with_bboxes)

Changelog

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymot-0.0.5.tar.gz (43.0 MB view details)

Uploaded Source

Built Distribution

pymot-0.0.5-py3-none-any.whl (43.0 MB view details)

Uploaded Python 3

File details

Details for the file pymot-0.0.5.tar.gz.

File metadata

  • Download URL: pymot-0.0.5.tar.gz
  • Upload date:
  • Size: 43.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.28.1

File hashes

Hashes for pymot-0.0.5.tar.gz
Algorithm Hash digest
SHA256 d149045d352bbdae14f2dfb7fee4338884c8e139a2abf6bbe70cd3f3f0269f58
MD5 ca0db34b2ab9fc28e1e9db5770011e47
BLAKE2b-256 fa854629d5d30617e302912b1abfe81d944716d83be4d33efee015204609cbb5

See more details on using hashes here.

File details

Details for the file pymot-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: pymot-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 43.0 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.28.1

File hashes

Hashes for pymot-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 123665513ad2b1bb722973e4aa7494ab56460055e7ddbc561acece45a5011448
MD5 5b5817f0131821a0b4ce4c1910a6fe70
BLAKE2b-256 5e7a15bb7bef20f564b0c2388e3ec8d94df76805eb5f1cb22d3c8e05b76a1d2b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page