2015-09-28 6 views
0

Я записал код, который может обнаружить движущийся объект на устойчивом фоне и вернуть расширенное двоичное пятно, которое можно использовать для отслеживания положения в течение x, y, используя метод «cv2.findContours» в режиме реального времени. Моя проблема в том, что когда я запускаю этот код, он показывает, что два пятна - это стабильное пятно, которое показывает точное начальное положение объекта, а одно место непрерывно перемещается и показывает текущую позицию в реальном времени. Теперь я просто хочу, чтобы показать позицию в режиме реального времени, а в стабильном местеобъект оставлен, но он показывает стабильную начальную следность вместе с отслеживателем движущихся объектов

import scipy.misc 
import cv2 
import time 

cam = cv2.VideoCapture("VID_20150401_191129.3gp") 

r, f1 = cam.read() 
f1 = scipy.misc.imresize(f1, 0.4) 

while(1): 


    r2, f2 = cam.read() 
    f2 = scipy.misc.imresize(f2, 0.4) 




    frameDelta = cv2.absdiff(f2,f1) 
    thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1] 
    thresh = cv2.dilate(thresh, None, iterations=4) 

    cv2.imshow('im',thresh) 

    k = cv2.waitKey(30) & 0xff 
    if k == 27: 
     break 

ответ

0

В этом коде вы делаете, что установка начального кадра (чтение изображения здесь r, f1 = cam.read() f1 является фреймом) в качестве фона кадра а кадр считывания в качестве текущего кадра. Вы вычитаете первый кадр с остальными кадрами. Чтобы получить объекты движения, вы можете использовать другую функцию, называемую backgroundUpdate. как это

def backgroundUpdate(): backgroundFrame = np.uint8((0.1* currentFrame) + ((0.9) * previousFrame))

Здесь текущий кадр является рамка считывания и предыдущий кадр последнего чтения.

Так вот ваш код может быть изменен, как этот

cam = cv2.VideoCapture("VID_20150401_191129.3gp") 

while(1): 
    r, currentFrame = cam.read() 
    currentFrame = scipy.misc.imresize(f2, 0.4) 
    previousFrame = currentFrame 

    if backgroundFrame is None: 
     previousFrame = currentFrame 
     backgroundUpdate() 
    else: 
     backgroundUpdate() 

    previousFrame = currentFrame  
    frameDelta = cv2.absdiff(backgroundFrame, currentFrame) 
    thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1] 
    thresh = cv2.dilate(thresh, None, iterations=4) 

    cv2.imshow('im',thresh) 

    k = cv2.waitKey(30) & 0xff 
    if k == 27: 
     break` 

backgroundUpdate функция обновляет backgroundFrame через вне захвата. Это даст хороший результат и небольшие движения также пренебрегают. Убедитесь, что обе функции имеют доступ к переменным. Для этого вы можете использовать global.

И для более оптимального решения после захвата вы можете использовать серое преобразование и размытие. Вот для этого код.

In [1]: currentFrame = cv2.cvtColor(Frame, cv2.COLOR_BGR2GRAY) In [2]: currentFrame = cv2.GaussianBlur(currentFrame, (25, 25), 0)

+0

Спасибо за ваши комментарии. Его показ «NameError: name« backgroundFrame »не определен», что я должен делать. – jax

+0

В начале функции перед циклом while просто объявляем 'backgroundFrame = None'. Тогда это решит. –

+0

Эй, спасибо, я уже это сделал, но теперь он показывает такую ​​ошибку: Ошибка OpenCV: размеры входных аргументов не совпадают (операция не является «массивом op array» (где массивы имеют одинаковый размер и одинаковое количество каналов), или 'array op scalar', или 'scalar op array') в arithm_op, файл /build/buildd/opencv-2.3.1/modules/core/src/arithm.cpp, строка 1253 Traceback (последний последний вызов): Файл «stack.py», строка 26, в frameDelta = cv2.absdiff (backgroundFrame, currentFrame) – jax