2010-07-30 42 views
12

Posso ottenere i frame dalla mia webcam utilizzando OpenCV in Python. L'esempio di camshift è vicino a quello che voglio, ma non voglio che l'intervento umano definisca l'oggetto. Voglio ottenere il punto centrale dei pixel totali che sono cambiati nel corso di diversi fotogrammi, cioè il centro dell'oggetto in movimento.Come faccio a tracciare il movimento usando OpenCV in Python?

+0

http://stackoverflow.com/questions/3374422/how-do-i-track-a-blob-using-opencv-and-python per il contesto domanda –

risposta

30

Ho un po 'di codice di lavoro tradotto dalla versione C di codice trovato nel post 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

Ho ricevuto alcuni video su http://appdelegateinc.com/blog/2010/08/02/motion-tracking-with-a-webcam/ –

+0

Grazie per il tuo codice. Funziona e può rilevare tutti gli oggetti in movimento. Tuttavia, non può tracciare l'oggetto in movimento. C'è un modo migliore per rintracciare oggetti in movimento? Sto pensando di calcolare il centro di ogni contorno, posso confrontare la posizione cambiata tra 2 fotogrammi, ma la parte difficile è, se ci sono molti contorni in una cornice, e ci sono molto vicini, è difficile dire per un contorno, che è il prossimo contorno nel prossimo fotogramma. – qkzhu

+0

È passato un po 'di tempo da quando usavo OpenCV, ma ricordo di aver utilizzato una demo inclusa con la sorgente, in cui trascinare un quadrato attorno ad un oggetto con il mouse per tracciare. Afferra l'istogramma di colore della selezione e lo cerca. Credo che sia stato questo pezzo di codice: https://code.ros.org/trac/opencv/browser/trunk/opencv/samples/python/camshift.py?rev=2136 –

1

Vedere il post del forum Motion tracking using OpenCV.

Credo che tu sia in grado di leggere e tradurre il codice sorgente a Python, giusto?

+0

darò una prova e farti sapere. –

+0

L'ho convertito in Python, ma temo di avere gli stessi punti ogni volta dopo aver chiamato CalcOpticalFlowPyrLK. Qualche idea? Ecco il mio codice: 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)); 

Questa è la parte del codice ho cercato di ottenere il centro dell'oggetto in movimento quando tracciato utilizzando un limite rettangolare.

0

Il seguente collegamento tiene traccia dei veicoli in movimento e del loro conteggio. È basato su OpenCV ed è scritto in Python 2.7.
OpenCV and Python

Problemi correlati