2010-07-30 18 views
12

Puedo obtener marcos de mi cámara web usando OpenCV en Python. El ejemplo de la caja de cambios está cerca de lo que quiero, pero no quiero que la intervención humana defina el objeto. Quiero obtener el punto central de los píxeles totales que han cambiado en el transcurso de varios fotogramas, es decir, el centro del objeto en movimiento.¿Cómo rastreo el movimiento usando OpenCV en Python?

+0

http://stackoverflow.com/questions/3374422/how-do-i-track-a-blob-using-opencv-and-python para el contexto pregunta –

Respuesta

30

Tengo algo de código de trabajo traducido de la versión C de código que se encuentra en la entrada del blog Motion Detection using OpenCV:

#!/usr/bin/env python 

import cv 

class Target: 

    def __init__(self): 
     self.capture = cv.CaptureFromCAM(0) 
     cv.NamedWindow("Target", 1) 

    def run(self): 
     # Capture first frame to get size 
     frame = cv.QueryFrame(self.capture) 
     frame_size = cv.GetSize(frame) 
     color_image = cv.CreateImage(cv.GetSize(frame), 8, 3) 
     grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1) 
     moving_average = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_32F, 3) 

     first = True 

     while True: 
      closest_to_left = cv.GetSize(frame)[0] 
      closest_to_right = cv.GetSize(frame)[1] 

      color_image = cv.QueryFrame(self.capture) 

      # Smooth to get rid of false positives 
      cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3, 0) 

      if first: 
       difference = cv.CloneImage(color_image) 
       temp = cv.CloneImage(color_image) 
       cv.ConvertScale(color_image, moving_average, 1.0, 0.0) 
       first = False 
      else: 
       cv.RunningAvg(color_image, moving_average, 0.020, None) 

      # Convert the scale of the moving average. 
      cv.ConvertScale(moving_average, temp, 1.0, 0.0) 

      # Minus the current frame from the moving average. 
      cv.AbsDiff(color_image, temp, difference) 

      # Convert the image to grayscale. 
      cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY) 

      # Convert the image to black and white. 
      cv.Threshold(grey_image, grey_image, 70, 255, cv.CV_THRESH_BINARY) 

      # Dilate and erode to get people blobs 
      cv.Dilate(grey_image, grey_image, None, 18) 
      cv.Erode(grey_image, grey_image, None, 10) 

      storage = cv.CreateMemStorage(0) 
      contour = cv.FindContours(grey_image, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) 
      points = [] 

      while contour: 
       bound_rect = cv.BoundingRect(list(contour)) 
       contour = contour.h_next() 

       pt1 = (bound_rect[0], bound_rect[1]) 
       pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) 
       points.append(pt1) 
       points.append(pt2) 
       cv.Rectangle(color_image, pt1, pt2, cv.CV_RGB(255,0,0), 1) 

      if len(points): 
       center_point = reduce(lambda a, b: ((a[0] + b[0])/2, (a[1] + b[1])/2), points) 
       cv.Circle(color_image, center_point, 40, cv.CV_RGB(255, 255, 255), 1) 
       cv.Circle(color_image, center_point, 30, cv.CV_RGB(255, 100, 0), 1) 
       cv.Circle(color_image, center_point, 20, cv.CV_RGB(255, 255, 255), 1) 
       cv.Circle(color_image, center_point, 10, cv.CV_RGB(255, 100, 0), 1) 

      cv.ShowImage("Target", color_image) 

      # Listen for ESC key 
      c = cv.WaitKey(7) % 0x100 
      if c == 27: 
       break 

if __name__=="__main__": 
    t = Target() 
    t.run() 
+1

Obtuve un video de él en http://appdelegateinc.com/blog/2010/08/02/motion-tracking-with-a-webcam/ –

+0

Gracias para tu código Funciona, y puede detectar todos los objetos en movimiento. Sin embargo, no puede rastrear el objeto en movimiento. ¿Hay alguna forma mejor de rastrear objetos en movimiento? Estoy pensando en calcular el centro de cada contorno, puedo comparar la posición cambiada entre 2 cuadros, pero la parte difícil es, si hay muchos contornos en un marco, y hay muy cerca, es difícil saber si hay un contorno, que es el siguiente contorno en el siguiente cuadro. – qkzhu

+0

Ha pasado un tiempo desde que utilicé OpenCV, pero recuerdo haber usado una demostración incluida con la fuente, donde arrastras un cuadrado alrededor de un objeto con el mouse para rastrear. Toma el histograma de color de la selección y lo busca. Creo que fue este código: https://code.ros.org/trac/opencv/browser/trunk/opencv/samples/python/camshift.py?rev=2136 –

1

Ver el mensaje en el foro Motion tracking using OpenCV.

Creo que eres capaz de leer y traducir el código fuente a Python, ¿verdad?

+0

Voy a darle una oportunidad y dejarte saber. –

+0

Lo convertí en Python, pero me temo que obtengo los mismos puntos cada vez que llamo a CalcOpticalFlowPyrLK. ¿Algunas ideas? Aquí está mi código: http://friendpaste.com/7lM9Cmiyif1fIVwrgKBJnG –

0
if faces: 
    for ((x, y, w, h), n) in faces: 
     pt1 = (int(x * image_scale), int(y * image_scale)) 
     pt2 = (int((x + w) * image_scale), int((y + h) * image_scale)) 
     ptcx=((pt1[0]+pt2[0])/2)/128 
     ptcy=((pt1[1]+pt2[1])/2)/96 
     cv.Rectangle(gray, pt1, pt2, cv.RGB(255, 0, 0), 3, 8, 0) 
     print ptcx; 
     print ptcy; 
     b=('S'+str(ptcx)+str(ptcy)); 

Esta es la parte del código que he intentado conseguir el centro del objeto en movimiento cuando se rastrea utilizando un límite rectangular.

0

Este siguiente enlace rastrea los vehículos en movimiento y los cuenta. Está basado en OpenCV y está escrito en Python 2.7.
OpenCV and Python