2010-12-21 20 views
8

Ich haue immer noch zusammen ein Buch Scanscript, und für jetzt, alles was ich brauche, ist in der Lage, automatisch eine Seitendrehung zu erkennen. Das Buch füllt 90% des Bildschirms aus (ich verwende eine grobe Webcam für die Bewegungserkennung), wenn ich also eine Seite umblättere, ist die Bewegungsrichtung grundsätzlich in derselben Richtung.Python OpenCV: Eine allgemeine Bewegungsrichtung erkennen?

Ich habe ein bewegungs Tracking-Skript geändert, aber Derivate werden immer mich nirgends:

#!/usr/bin/env python 

import cv, numpy 

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) 
     grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1) 
     moving_average = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_32F, 3) 
     difference = None 
     movement = [] 

     while True: 
      # Capture frame from webcam 
      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 not difference: 
       # Initialize 
       difference = cv.CloneImage(color_image) 
       temp = cv.CloneImage(color_image) 
       cv.ConvertScale(color_image, moving_average, 1.0, 0.0) 
      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 object blobs 
      cv.Dilate(grey_image, grey_image, None, 18) 
      cv.Erode(grey_image, grey_image, None, 10) 

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

      while contour: 
       # Draw rectangles 
       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) 

      num_points = len(points) 

      if num_points: 
       x = 0 
       for point in points: 
        x += point[0] 
       x /= num_points 

       movement.append(x) 

      if len(movement) > 0 and numpy.average(numpy.diff(movement[-30:-1])) > 0: 
       print 'Left' 
      else: 
       print 'Right' 

      # Display frame to user 
      cv.ShowImage("Target", color_image) 

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

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

Es erkennt die durchschnittliche Bewegung des durchschnittlichen Zentrum alle Felder, die extrem ineffizient ist. Wie würde ich solche Bewegungen schnell und genau erkennen (d. H. Innerhalb eines Grenzwerts)?

Ich benutze Python, und ich plane, dabei zu bleiben, da mein gesamtes Framework auf Python basiert.

Und Hilfe wird geschätzt, also danke Ihnen allen im Voraus. Prost.

+0

Brauchen Sie wirklich das Motion-Tracking? Warum erkennen Sie nicht einfach Änderungen über einen bestimmten Schwellenwert? (d. h. etwas in der Form von 'sum (abs (img2 - img1))> Schwelle') –

+0

Hmm, ich werde damit herumspielen. Aber wie sollte ich sagen, ob die Seite nach vorne oder nach hinten gedreht wurde, oder noch schlimmer, auf halbem Weg und dann wieder zurück? Ich werde mit den Graphen spielen, denn so arbeite ich. Vielen Dank! – Blender

+0

Ah, wahr, ich habe nur angenommen, dass du wissen musst, dass eine Seite umgedreht wurde ... Wenn du die Richtung wissen musst, ist mein Kommentar oben eindeutig keine gute Wahl! –

Antwort

2

Ich habe nicht OpenCV in Python zuvor verwendet, nur ein bisschen in C++ mit Openframeworks.

Dafür nehme ich OpticalFlow 's Velx, vely Eigenschaften würde funktionieren.

Weitere Informationen zur Funktionsweise von Optical Flow finden Sie unter this paper.

HTH

+0

Oooooh! Das sieht glänzend aus. Ich werde das auf jeden Fall überprüfen, da dies das zu sein scheint, wonach ich suche. – Blender

+0

Ich habe es, aber ich kann nicht herausfinden, was passiert. Ich bekomme eine Fluktuation in 'Velx', aber es ist zufällig in positiver oder negativer Richtung. Hast du etwas, was ich sehen kann? Das scheint etwas zu sein, das ich benutzen kann, aber ich kann einfach nicht herausfinden, wie ... – Blender

+0

Ein bisschen spät, aber ich habe ein Demo-Paket von OpenCVs Python-Bindings an meine Bedürfnisse angepasst. Vielen Dank! – Blender

0

warum verwenden Sie nicht cv.GoodFeaturesToTrack? Es kann die Laufzeit des Skripts lösen ... und den Code verkürzen ...