代码之家  ›  专栏  ›  技术社区  ›  MNM

python中背景相减的质心跟踪

  •  0
  • MNM  · 技术社区  · 6 年前

    因此,我一直在遵循本教程进行质心跟踪 https://www.pyimagesearch.com/2018/07/23/simple-object-tracking-with-opencv/ 并且像教程中提到的那样构建了质心跟踪类。

    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)
    

    以下是本教程中质心跟踪器的实现:

    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 回复  |  直到 6 年前
        1
  •  2
  •   Axel Puig    6 年前

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

        2
  •  2
  •   MNM    6 年前

    按照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)
    

    这解决了问题。我想发生的是第一帧没有初始化跟踪器,所以我需要确保它不是空的,然后它就工作了