通过在 python 中使用背景减法进行质心跟踪

Centroid Tracking with by using background subtracting in python

所以我一直在按照本教程进行质心跟踪 https://www.pyimagesearch.com/2018/07/23/simple-object-tracking-with-opencv/ 并像教程中提到的那样构建了质心跟踪 class。

现在,当我尝试使用背景减法而不是他正在使用的 CNN 进行检测时,它不起作用,并从 CentroidTracker.py

给我这个问题
for i in range(0, inputCentroids):
TypeError: only integer scalar arrays can be converted to a scalar index

这是我正在使用的代码

for i in range(0, num_frames):
rects = []
#Get the very first image from the video
if (first_iteration == 1):
    ret, frame = cap.read()
    frame = cv2.resize(frame, (imageHight,imageWidth))
    first_frame = copy.deepcopy(frame)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    height, width = frame.shape[:2]
    print("shape:", height,width)
    first_iteration = 0

else:
    ret, frame = cap.read()
    frame = cv2.resize(frame, (imageHight,imageWidth))
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    forgroundMask = backgroundSub.apply(frame)

    #Get contor for each person
    _, contours, _ = cv2.findContours(forgroundMask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    contours = filter(lambda cont: cv2.contourArea(cont) > 20, contours)
    #Get bbox from the controus
    for c in contours:
        (x, y, w, h) = cv2.boundingRect(c)
        rectangle = [x, y, (x + w), (y + h)]
        rects.append(rectangle)
        cv2.rectangle(frame, (rectangle[0], rectangle[1]), (rectangle[2], rectangle[3]),
                      (0, 255, 0), 2)

    objects = ct.update(rects)

    for (objectID, centroid) in objects.items():
        text = "ID:{}".format(objectID)
        cv2.putText(frame, text, (centroid[0] - 10, centroid[1] - 10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
        cv2.circle(frame, (centroid[0], centroid[1]), 4, (0, 255, 0), -1)


    '''Display Windows'''
    cv2.imshow('FGMask', forgroundMask)
    frame1 = frame.copy()
    cv2.imshow('MOG', frame1)
cv2.imshow('frame', frame)



if cv2.waitKey(1) & 0xFF == ord('q'):
    break

代码在

处被破坏
objects = ct.update(rects)

行。

这是教程中 CentroidTracker 的实现:

from scipy.spatial import distance as dist
from collections import OrderedDict
import numpy as np

#Makes a the next unique object ID with
#2 ordered dictionaries
class CentroidTracker():
    def __init__(self, maxDisappeared = 50):
        self.nextObjectID = 0
        self.objects = OrderedDict()
        self.disappeared = OrderedDict()
        self.maxDisappeared = maxDisappeared

    def register(self, centroid):
        self.objects[self.nextObjectID] = centroid
        self.disappeared[self.nextObjectID] = 0
        self.nextObjectID += 1

    def deregister(self, objectID):
        del self.objects[objectID]
        del self.disappeared[objectID]

    def update(self, rects):
        if len(rects) == 0:
        for objectID in self.disappeared.keys():
            self.disappeared[objectID] += 1
            if self.disappeared[objectID] > self.maxDisappeared:
                self.deregister(objectID)
        return self.objects
    inputCentroids = np.zeros((len(rects), 2), dtype="int")
    for (i, (startX, startY, endX, endY)) in enumerate(rects):
        cX = int((startX + endX) / 2.0)
        cY = int((startY + endY) / 2.0)
        inputCentroids[i] = (cX, cY)
    if len(self.objects) == 0:
        for i in range(0, inputCentroids):
            self.register(inputCentroids[i])
    else:
        objectIDs = list(self.objects.keys())
        objectCentroids = list(self.objects.values())
        D = dist.cdist(np.array(objectCentroids), inputCentroids)
        rows = D.min(axis=1).argsort()
        cols = D.argmin(axis=1)[rows]

        usedRows = set()
        usedCols = set()

        for (row, col) in zip(rows, cols):
            if row in usedRows or col in usedCols:
                continue
            objectID = objectIDs[row]
            self.objects[objectID] = inputCentroids[col]
            self.disappeared[objectID] = 0
            usedRows.add(row)
            usedCols.add(col)
            # compute both the row and column index we have NOT yet
            # examined
            unusedRows = set(range(0, D.shape[0])).difference(usedRows)
            unusedCols = set(range(0, D.shape[1])).difference(usedCols)
            if D.shape[0] >= D.shape[1]:
                # loop over the unused row indexes
                for row in unusedRows:
                    # grab the object ID for the corresponding row
                    # index and increment the disappeared counter
                    objectID = objectIDs[row]
                    self.disappeared[objectID] += 1

                    # check to see if the number of consecutive
                    # frames the object has been marked "disappeared"
                    # for warrants deregistering the object
                    if self.disappeared[objectID] > self.maxDisappeared:
                        self.deregister(objectID)
            else:
                for col in unusedCols:
                    self.register(inputCentroids[col])

                # return the set of trackable objects
            return self.objects

我有点迷失在我在这里做错了什么。我应该做的就是将边界框 (x,y,x+w, y+h) 传递到正确的 rects[] 列表中,并且应该为此给出类似的结果,或者我错了并且不明白这是如何工作的?任何帮助将不胜感激

您忘记了 len 函数:for i in range(0, len(inputCentroids)):

按照 Axel Puig 所说的进行操作,然后将此行添加到主方法中

objects = ct.update(rects)
    if objects is not None:
        for (objectID, centroid) in objects.items():
            text = "ID:{}".format(objectID)
            cv2.putText(frame, text, (centroid[0] - 10, centroid[1] - 10),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
            cv2.circle(frame, (centroid[0], centroid[1]), 4, (0, 255, 0), -1)

这解决了问题。我认为发生的事情是第一帧没有初始化跟踪器所以我需要确保它不是 None 然后它在那之后工作