Отслеживание Centroid с использованием вычитания фона в Python - PullRequest
0 голосов
/ 04 декабря 2018

Итак, я следовал этому руководству по отслеживанию центроидов https://www.pyimagesearch.com/2018/07/23/simple-object-tracking-with-opencv/ и создал класс отслеживания центроидов, как он упоминает в учебнике.

Теперь, когда я пытаюсь использовать вычитание фона для обнаружения вместо 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 [], и это должно дать аналогичные результаты для этого, или я ошибаюсь и не понимаю, как это работает?Любая помощь будет оценена

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Сделав то, что сказал Аксель Пуиг, а затем добавив эту строку в основной метод

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, тогда он работал после этого

0 голосов
/ 04 декабря 2018

Вы забыли функцию len: for i in range(0, len(inputCentroids)):

...