Сохраняйте одинаковую метку для движущегося объекта, используя opencv - PullRequest
0 голосов
/ 20 мая 2018

Я хочу отследить движущуюся рыбу с камеры, которая находится на вершине аквариума.До сих пор я мог отслеживать несколько движущихся объектов, используя методы скользящего среднего и вычитания фона.И я положил текст на каждый контур.Но проблема в том, что я не могу держать один и тот же ярлык для одной и той же движущейся рыбы.Рыба может обнаружить с каждого кадра, но номер отслеживаемого объекта меняется.Я приложил свой текущий код Python.?Что я здесь не так делаю?Может кто-нибудь сказать мне другой возможный способ сделать это.

Спасибо

import cv2
import numpy as np

device = cv2.VideoCapture(0)
flag, frame = device.read()
movingaverage = np.float32(frame)
background = cv2.createBackgroundSubtractorMOG2()
font=cv2.FONT_HERSHEY_SIMPLEX
kernelOpen=np.ones((5,5))
kernelClose=np.ones((20,20))

while True:

    flag, frame = device.read()
    alpha = float(1.0/2.0) 
    cv2.accumulateWeighted(frame,movingaverage,alpha)

    gaussion = background.apply(frame)

    res = cv2.convertScaleAbs(movingaverage)
    difference_img = cv2.absdiff(res, frame)
    grey_difference_img = cv2.cvtColor(difference_img, cv2.COLOR_BGR2GRAY)
    ret,th1 = cv2.threshold(grey_difference_img, 10, 255, cv2.THRESH_BINARY)

    combine = cv2.bitwise_and(gaussion, gaussion, mask = grey_difference_img)
    _, conts, h1 =cv2.findContours(combine.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)


    if len(conts) == 0:
        cv2.putText(frame,"No moving objects found!",(50,200), font, 1,(255,255,255),2,cv2.LINE_AA)

    else:
        number = 0
        for i in range(len(conts)):
            x,y,w,h = cv2.boundingRect(conts[i])
            if (w > 50) and (h > 50):
                cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255), 2)      
                cv2.putText(frame,str(number +1)+ "object",(x,y+h), font, 1,(255,255,255),2,cv2.LINE_AA)
                number = number + 1

    cv2.imshow("Gaussian",gaussion)
    cv2.imshow("Track",frame)

    if cv2.waitKey(1) == 27:
       break

device.release()
cv2.destroyAllWindows()

У меня есть идея, но я не уверен в этом.Теперь я изменил код, чтобы определить центр каждого контура.Итак, могу ли я сохранить информацию о координатах в массиве, а затем проверить новую центральную точку контуров кадра так, чтобы она была близка к значениям массива.затем попытайтесь угадать контур, который хранится в массиве в предыдущем кадре.Я не знаю возможности этого, так как я новичок в python и opencv.

if (w > 50) and (h > 50):
    cnt = conts[i]
    M = cv2.moments(cnt)
    if M['m00'] != 0:
        cx = int(M['m10']/M['m00'])
        cy = int(M['m01']/M['m00'])
        #draw a circle at center of contours.
        cv2.circle(frame,(cx,cy), 2, (0,0,255), -1)
        print( "(",cx,",",cy,")" )
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255), 2)      
        cv2.putText(frame,str(number +1)+ "object",(x,y+h), font, 1,(255,255,255),2,cv2.LINE_AA)

1 Ответ

0 голосов
/ 26 мая 2018

Я отредактировал свой код.Теперь все работает нормально, если движущиеся объекты находятся в одной горизонтальной плоскости.Я создал список matched_contours и paths.Затем добавьте вычисленные центральные точки в paths, что в элементе matched_contours.И использовал min_dist, чтобы проверить, представлены ли контуры в предыдущем кадре или нет.Если он был представлен, я обновил новые центральные точки в matched_contour.Если нет, я воспринял это как новый matched_contour.

ЭТО ОБНОВЛЕННАЯ ЧАСТЬ

im2, contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)
for (_, contour) in enumerate(contours):
    (x, y, w, h) = cv2.boundingRect(contour)
    if (w >= 50) or (h >= 50): # Find targeting size moving objects
        x1 = int(w / 2)
        y1 = int(h / 2)
        cx = x + x1
        cy = y + y1

        if len(matched_contours) == 0: #No previous moving objects
            paths = []
            paths.append((cx,cy))
            object_num = object_num + 1
            matched_contours.append(((x, y, w, h), (cx,cy), object_num, paths))
            cv2.circle(frame,(cx,cy), 2, (0,0,255), -1)
            #cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255), 2)
            rect = cv2.minAreaRect(contour)
            box = cv2.boxPoints(rect)
            box = np.int0(box)
            cv2.drawContours(frame,[box],0,(0,255,0),2)
            cv2.putText(frame,"object " + str(object_num),(x,y+h), font, 0.5,(255,255,255),1,cv2.LINE_AA)

        else:
            found = False
            for i in range(len(matched_contours)):
                ponits, center, num, path = matched_contours[i]
                old_cx, old_cy = center
                #Calculate euclidian distances between new center and old centers to check this contour is existing or not
                euc_dist = math.sqrt(float((cx - old_cx)**2) + float((cy - old_cy)**2))

                if euc_dist <= min_dist:          
                    if len(path) == max_path_length:
                        for t in range(len(path)):
                            if t == max_path_length - 1:
                                path[t] = (cx,cy)
                            else:
                                path[t] = path[t+1]
                    else:
                        path.append((cx,cy))                                                  
                    matched_contours[i] = ((x, y, w, h), (cx,cy), num, path)
                    cv2.circle(frame,(cx,cy), 2, (0,0,255), -1)
                    #cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255), 2)
                    rect = cv2.minAreaRect(contour)
                    box = cv2.boxPoints(rect)
                    box = np.int0(box)
                    cv2.drawContours(frame,[box],0,(0,255,0),2)
                    cv2.putText(frame,"object " + str(num),(x,y+h), font, 0.5,(255,255,255),1,cv2.LINE_AA)    
                    #Draw path of the moving object
                    for point in range(len(path)-1):
                        cv2.line(frame, path[point], path[point+1], (255,0,0), 1)
                        cv2.circle(frame,path[point+1], 3, (0,0,255), -1)                            

            if not found: #New moving object has found
                object_num = object_num + 1
                paths = []
                paths.append((cx,cy))
                matched_contours.append(((x, y, w, h), (cx,cy), object_num, paths))
                cv2.circle(frame,(cx,cy), 2, (0,0,255), -1)
                #cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255), 2)
                rect = cv2.minAreaRect(contour)
                box = cv2.boxPoints(rect)
                box = np.int0(box)
                cv2.drawContours(frame,[box],0,(0,255,0),2)
                cv2.putText(frame,"object " + str(object_num),(x,y+h), font, 0.5,(255,255,255),1,cv2.LINE_AA)

Надеюсь, это полезно ..

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