Программное обеспечение для подсчета объектов с использованием opencv - PullRequest
0 голосов
/ 31 октября 2019

Я работаю над подсчетом программного обеспечения. Я успешно обнаружил продукты и хочу их посчитать. Для подсчета я определил две линии, и если центроид находится между двумя линиями, произведение считается. Две проблемы, с которыми я сталкиваюсь. Во-первых, поскольку мой продукт идет очень быстро, некоторые продукты не попадают между строк, поэтому я увеличил пространство строк. Во-вторых, после увеличения линейного пространства, если продукты падают в два раза, это считается в два раза. Я пытался поместить centroid в список, и если продукты учитываются один раз, я удаляю элементы списка. Считать дважды или неправильно. Пожалуйста помоги. Вот ссылка на видео https://drive.google.com/file/d/1Gqp937OlDpF4_Nx2kSOzHw3A85Xch-HX/view?usp=sharing

import cv2
import math
import numpy as np

width = 0
height = 0
EntranceCounter = 0
ExitCounter = 0
OffsetRefLines = 120
QttyOfContours = 0
area = 0
detect = []
area_min = 100
area_max = 4000

BinarizationThreshold = 70

#Check if an object in entering in monitored zone
##def CheckEntranceLineCrossing(CoordYCentroid, CoorYEntranceLine,CoorYExitLine,area):
##    AbsDistance = abs(CoordYCentroid - CoorYEntranceLine) 
##    if ((y>CoorYEntranceLine) and (y < CoorYExitLine) ):#and area>=5000):
##      return 1
##  #else:
##      #return 0

cap = cv2.VideoCapture('testvideo.avi')


while(cap.isOpened()):
    ret, frame = cap.read()
    height = np.size(frame,0)
    width = np.size(frame,1)


    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    _, threshold = cv2.threshold(frame, 100, 255, cv2.THRESH_BINARY)
    low = np.array([0,0,0])
    high = np.array([60, 60, 60])
    image_mask = cv2.inRange(threshold,low, high)
    contours,_= cv2.findContours(image_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

    cv2.drawContours(frame, contours, -1, (0,255,0), 3)
    CoorYEntranceLine = int(150-OffsetRefLines)
    CoorYExitLine = int(150+OffsetRefLines)
    cv2.line(threshold, (0,CoorYEntranceLine), (width,CoorYEntranceLine), (0, 255, 0), 2)
    cv2.line(threshold , (0,CoorYExitLine), (width,CoorYExitLine), (0, 0, 255), 2)


    for (i,c)  in enumerate(contours):
        new = True
        QttyOfContours = QttyOfContours+1
        (x, y, w, h) = cv2.boundingRect(c)
        cv2.rectangle(threshold, (x, y), (x + w, y + h), (0, 0, 255), 2)
        area = cv2.contourArea(c)
        if area< area_min:
            continue
        #find object's centroid
        CoordXCentroid = int((x+x+w)/2)
        CoordYCentroid = int((y+y+h)/2)
        ObjectCentroid = (CoordXCentroid,CoordYCentroid)
        #center = pega_centro(x, y, w, h)
        center = (CoordXCentroid,CoordYCentroid)
        detect.append(center)


        for (x,y) in detect:
            if ((y < CoorYExitLine) and (y>CoorYEntranceLine) and (area>area_min) and (area<area_max)):
                if new ==True:
                    EntranceCounter += 1
                    detect.clear()
                    break


        cv2.putText(frame, str(EntranceCounter), ((CoordXCentroid),(CoordYCentroid-50)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

    cv2.putText(threshold, "Entrances: {}".format(str(EntranceCounter)), (10, 50),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (250, 0, 1), 2)                            

    cv2.imshow('fram1',threshold)
    cv2.imshow('frame',frame)
    if cv2.waitKey(1)==27:
        break

cap.release()
cv2.destroyAllWindows()


1 Ответ

0 голосов
/ 01 ноября 2019

Просто проверьте пересечение линии счета и линии между текущей и предыдущей точками положения объекта. И, в качестве дополнительной гарантии, используйте флаг «считать» для отслеживаемых объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...