2012-12-03 11 views
8

Grazie mille, se qualcuno può aiutarmi. Im provare, utilizzare un esempio di libro "OReilly Programming Computer Vision con Python", alla fine della pagina 216.OpenCV Python calcOpticalFlowFarneback

#!/usr/bin/env python 

import cv2 
def draw_flow(im,flow,step=16): 
    h,w = im.shape[:2] 
    y,x = mgrid[step/2:h:step,step/2:w:step].reshape(2,-1) 
    fx,fy = flow[y,x].T 

    # create line endpoints 
    lines = vstack([x,y,x+fx,y+fy]).T.reshape(-1,2,2) 
    lines = int32(lines) 

    # create image and draw 
    vis = cv2.cvtColor(im,cv2.COLOR_GRAY2BGR) 
    for (x1,y1),(x2,y2) in lines: 
     cv2.line(vis,(x1,y1),(x2,y2),(0,255,0),1) 
     cv2.circle(vis,(x1,y1),1,(0,255,0), -1) 
    return vis 


cap = cv2.VideoCapture(0) 

ret,im = cap.read() 
prev_gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) 

while True: 
    # get grayscale image 
    ret,im = cap.read() 
    gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) 

    # compute flow 
    #flow = cv2.calcOpticalFlowFarneback(prev_gray,gray,None,0.5,3,15,3,5,1.2,0) 
    flow = cv2.calcOpticalFlowFarneback(prev_gray,gray,float(0),float(0),3,15,3,5,float(1),0) 
    prev_gray = gray 

    # plot the flow vectors 
    cv2.imshow('Optical flow',draw_flow(gray,flow)) 
    if cv2.waitKey(10) == 27: 
     break 

Im eseguire a terminale (LXUbuntu, LXterminal) ed ottengo l'errore seguente:

VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
Traceback (most recent call last): 
    File "hw.py", line 35, in <module> 
    flow = cv2.calcOpticalFlowFarneback(prev_gray,gray,None,0.5,3,15,3,5,1.2,0) 
TypeError: a float is required 

Capisco che il problema è nella funzione calcOpticalFlowFarneback, perché questo ha bisogno di un numero in float, quindi, im provare calcOpticalFlowFarneback (prev_gray, gray, None, float (0.5), 3,15,3,5, float (1,2), 0) ma non funziona.

Grazie mille.

+0

"è richiesto un galleggiante" sarebbe probabilmente riferendo a non float, argomenti non int nella lista degli argomenti .. – asheeshr

risposta

13

È necessario modificare leggermente il codice.

Prima di tutto, includere la libreria Numpy poiché i metodi come mgrid, int32, vstack sono funzioni numpy.

Così, alla parte superiore del codice, aggiunge:

from numpy import * 

In secondo luogo, venendo alla tua domanda, quarto argomento dovrebbe essere un int. Lo hai fornito come galleggiante. Fallo 1 (o 3, come preferisci). E l'ultimo argomento viene prodotto da solo. Non ne hai bisogno. Quindi rimuovilo.

Quindi la mia dichiarazione finale assomigliare al di sotto (e funziona bene per me):

flow = cv2.calcOpticalFlowFarneback(prev_gray,gray,0.5,1,3,15,3,5,1) 

Prova questa, e fatemi sapere se ogni errore viene.

2

Quando invoco la funzione come segue, viene visualizzato il seguente messaggio di errore:

flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0) 

Errore:

flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0) 
TypeError: a float is required 

Quando si elimina il valore None poi il mio programma funziona correttamente:

flow = cv2.calcOpticalFlowFarneback(prvs, next, 0.5, 3, 15, 3, 5, 1.2, 0) 

La funzione calcOpticalFlowFarneback() prende forma:

cv2.calcOpticalFlowFarneback(prev, next, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags[, flow]) → flow 

Si scopre che non dobbiamo passare il valore di None per il parametro pyr_scale. Possiamo passare None al parametro flow.

  • pyr_scale: un parametro, che specifica la scala dell'immagine (< 1) per costruire piramidi per ogni immagine; pyr_scale = 0.5 significa una piramide classica, in cui ogni strato successivo è due volte più piccolo del precedente.

  • flow: immagine di flusso calcolata che ha le stesse dimensioni di prvs e digitare CV_32FC2.

+0

Come hanno notato, questo è commento non correlato, tuttavia ecco perché questo sta accadendo: Poiché la funzione accetta parametri diversi in python 2 e python 3. Quindi, assicurati di leggere il manuale che corrisponde al tuo ambiente. Puoi verificarlo con cv2.cv .__ versione__ – GrigorisG

3

@sunside

flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0) 

cv2.calcOpticalFlowFarneback(prev, next, flow, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags) → flow 

è grama opencv3.x, vedi alose opencv3.x doc

Altrimenti:

flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0) 
TypeError: a float is required 

cv2.calcOpticalFlowFarneback(prev, next, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags[, flow]) 

è necessario era corsa a opencv2.x, può essere asserito in questo modo:

import cv2 
print cv2.__version__ 

Vedi opencv2.x doc

1

Se si utilizza python3, inserire in def draw_flow

y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int) 
flow = cv2.calcOpticalFlowFarneback(prevgray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0) 

Per Python 2 si dovrebbe usare

y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1) 
flow = cv2.calcOpticalFlowFarneback(prevgray, gray, 0.5, 3, 15, 3, 5, 1.2, 0)