TypeError: tuple indices must be integers or slices, not tuple, in deepsort

507 Views Asked by At

I have been getting this error from the line tracker.update(dets).Exact error is

File "C:\Users\Admin\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\deep_sort\deep_sort\linear_assignment.py", line 65, in min_cost_matching
    if col not in indices[:, 1]:
TypeError: tuple indices must be integers or slices, not tuple

I have edited 'min_cost_matching' function in the linear_assignment.py file of the DeepSORT library to

if col not in indices[:, 1].tolist():

it didn't worked. So I checked inputs to the 'min_cost_matching' function I print its input and its something this

(array([ 0,  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], dtype=int64), array([ 0,  2,  1,  3,  5,  4,  7, 10,  9,  8, 12,  6, 18, 11, 13, 15, 19, 16, 17, 23, 20, 14, 29, 36, 21, 34, 26, 
27, 35, 24, 25, 31, 28, 30, 33, 32, 22], dtype=int64))

is this correct or not. Here is my full code

import os
import cv2
import random
import numpy as np
from ultralytics import YOLO
from deep_sort.deep_sort.tracker import Tracker
from deep_sort.deep_sort import nn_matching
from deep_sort.deep_sort.detection import Detection
from deep_sort.tools import generate_detections as gdet


video_path = os.path.join("people.mp4")
cap = cv2.VideoCapture(video_path)

ret, frame = cap.read()
model = YOLO("yolov8n.pt")

encoder_model_filename = 'C:\PycharmProjects\mars-small128.pb'
max_cosine_distance = 0.4
nn_budget = None
metric = nn_matching.NearestNeighborDistanceMetric(
    "cosine", max_cosine_distance, nn_budget)

tracker = Tracker(metric)
colors = [(random.randint(0, 255), random.randint(0, 255),
           random.randint(0, 255)) for j in range(10)]
while ret:
    results = model(frame)
    # print(results)
    for result in results:
        detections = []
        for r in result.boxes.data.tolist():
            x1, y1, x2, y2, score, classs_id = r
            x1 = int(x1)
            y1 = int(y1)
            x2 = int(x2)
            y2 = int(y2)
            detections.append([x1, y1, x2, y2, score])

        bboxes = np.asarray([d[:-1] for d in detections])
        # sets the width and heights of the bounding box
        bboxes[:, 2:] = bboxes[:, 2:] - bboxes[:, 0:2]
        # stores list containing confidence scores for each detection
        scores = [d[-1] for d in detections]
        
        encoder = gdet.create_box_encoder(encoder_model_filename, batch_size=1)
        features = encoder(frame, bboxes)

        dets =[]
        for bbox_id, bbox in enumerate(bboxes):
            dets.append(Detection(bbox, scores[bbox_id], features[bbox_id]))
            tracker.predict()
            tracker.update(dets)
            for track in tracker.tracks:
                print(track)
                # bbox = track.bbox
                x1, y1, x2, y2 = bbox
                track_id = track.track_id

        cv2.rectangle(frame, (int(x1), int(y1)),
                      (int(x2), int(y2)), (127, 255, 0), 2)

    cv2.imshow("frame", frame)
    cv2.waitKey(1)
    ret, frame = cap.read()

cap.release()
cv2.destroyAllWindows()

tools :- python :- 3.10.11 deepsort :- https://github.com/nwojke/deep_sort.git

I used this github repo code :- https://github.com/computervisioneng/object-tracking-yolov8-deep-sort.git

2

There are 2 best solutions below

1
Surya R On

Updated code of yours,

    import os
    import cv2
    import random
    import numpy as np
    from ultralytics import YOLO
    from deep_sort.deep_sort.tracker import Tracker
    from deep_sort.deep_sort import nn_matching
    from deep_sort.deep_sort.detection import Detection
    from deep_sort.tools import generate_detections as gdet


    video_path = os.path.join("people.mp4")
    cap = cv2.VideoCapture(video_path)

    ret, frame = cap.read()
    model = YOLO("yolov8n.pt")

    encoder_model_filename = 'C:\PycharmProjects\mars-small128.pb'
    max_cosine_distance = 0.4
    nn_budget = None
    metric = nn_matching.NearestNeighborDistanceMetric(
        "cosine", max_cosine_distance, nn_budget)

    tracker = Tracker(metric)
    colors = [(random.randint(0, 255), random.randint(0, 255),
               random.randint(0, 255)) for j in range(10)]
    while ret:
        results = model(frame)
        # print(results)
        for result in results:
            detections = []
            for r in result.boxes.data.tolist():
                x1, y1, x2, y2, score, classs_id = r
                x1 = int(x1)
                y1 = int(y1)
                x2 = int(x2)
                y2 = int(y2)
                detections.append([x1, y1, x2, y2, score])

            bboxes = np.asarray([d[:-1] for d in detections])
            # sets the width and heights of the bounding box
            bboxes[:2:] = bboxes[:2:] - bboxes[:0:2]
            # stores list containing confidence scores for each detection
            scores = [d[-1] for d in detections]
            
            encoder = gdet.create_box_encoder(encoder_model_filename, batch_size=1)
            features = encoder(frame, bboxes)

            dets =[]
            for bbox_id, bbox in enumerate(bboxes):
                dets.append(Detection(bbox, scores[bbox_id], features[bbox_id]))
                tracker.predict()
                tracker.update(dets)
                for track in tracker.tracks:
                    print(track)
                    # bbox = track.bbox
                    x1, y1, x2, y2 = bbox
                    track_id = track.track_id

            cv2.rectangle(frame, (int(x1), int(y1)),
                          (int(x2), int(y2)), (127, 255, 0), 2)

        cv2.imshow("frame", frame)
        cv2.waitKey(1)
        ret, frame = cap.read()

    cap.release()
    cv2.destroyAllWindows()

Tuples or List slicing happens like this

#A demo of extended slicing
a_List_slice = [10,20,30,40,50,60,70]
  
print("Original List:", a_List_slice)
 
print("Sliced List:", a_List_slice[2:6:1])

you have been using comma after the colon

0
samt On

I had the same problem, solved it by changing the linear_assignment.py file.

Mainly, changed the unpacking at line 58:

indices = linear_assignment(cost_matrix)

to

row_indices, col_indices = linear_assignment(cost_matrix)

It also required some minor changes, as follows:

def min_cost_matching(
        distance_metric, max_distance, tracks, detections, track_indices=None,
        detection_indices=None):

         ...

    row_indices, col_indices = linear_assignment(cost_matrix)

    matches, unmatched_tracks, unmatched_detections = [], [], []
    for col, detection_idx in enumerate(detection_indices):
        if col not in col_indices:
            unmatched_detections.append(detection_idx)
    for row, track_idx in enumerate(track_indices):
        if row not in row_indices:
            unmatched_tracks.append(track_idx)
    for row, col in zip(row_indices, col_indices):
        track_idx = track_indices[row]

         ...
         

Maybe the error occurred due to this change: https://stackoverflow.com/a/62391260/22180199

Hope it helps.