2012-12-03 35 views
8

Cảm ơn rất nhiều, nếu có ai có thể giúp tôi. Im cố gắng, sử dụng một ví dụ về cuốn sách "Oreilly Lập trình máy tính Vision với Python", ở cuối trang 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 thực hiện trong thiết bị đầu cuối (LXUbuntu, lxterminal) và tôi nhận được lỗi sau:

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 

Tôi hiểu rằng vấn đề nằm trong hàm calcOpticalFlowFarneback, vì điều này cần một số trong float, do đó, im thử calcOpticalFlowFarneback (prev_gray, gray, None, float (0.5), 3,15,3,5, float (1.2), 0) nhưng không hoạt động.

Thanks a lot.

+0

"một phao là cần thiết" có lẽ sẽ được đề cập đến phi các đối số float, non-int trong danh sách đối số .. – asheeshr

Trả lời

13

Bạn cần thay đổi mã một chút.

Trước hết, bao gồm thư viện Numpy vì các phương pháp như mgrid, int32, vstack là các chức năng gọn gàng.

Vì vậy, ở đầu của mã, thêm:

from numpy import * 

Thứ hai, đến câu hỏi của bạn, lập luận thứ tư phải là một int. Bạn đã cung cấp nó như là phao. Làm cho nó 1 (hoặc 3, như bạn muốn). Và đối số cuối cùng là đầu ra chính nó. Bạn không cần nó. Vì vậy, loại bỏ nó.

Vì vậy, tuyên bố cuối cùng của tôi trông giống như dưới đây (và nó hoạt động tốt đối với tôi):

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

Hãy thử điều này, và cho tôi biết nếu có lỗi xuất phát.

2

Khi tôi gọi hàm như sau, thông báo lỗi sau đây được hiển thị:

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

Lỗi:

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

Khi tôi xóa các giá trị None sau đó chương trình của tôi làm việc một cách chính xác:

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

Chức năng calcOpticalFlowFarneback() có hình dạng:

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

Nó chỉ ra rằng chúng ta không được chuyển giá trị None cho tham số pyr_scale. Chúng tôi có thể vượt qua None đến tham số flow.

  • pyr_scale: một tham số, xác định quy mô hình ảnh (< 1) để xây dựng kim tự tháp cho mỗi hình ảnh; pyr_scale = 0.5 có nghĩa là kim tự tháp cổ điển, trong đó mỗi lớp tiếp theo nhỏ hơn hai lần so với lớp trước.

  • flow: hình ảnh luồng được tính có cùng kích thước với prvs và nhập CV_32FC2.

+0

Như chúng đã lưu ý, đây là nhận xét không liên quan, tuy nhiên đây là lý do tại sao điều này xảy ra: Vì hàm này chấp nhận các tham số khác nhau trong python 2 và python 3. Vì vậy, hãy chắc chắn rằng bạn đang đọc hướng dẫn phù hợp với môi trường của bạn. Bạn có thể kiểm tra với cv2.cv .__ version__ – 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 

là một thứ cỏ opencv3.x, xem alose opencv3.x doc

Nếu không:

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]) 

bạn phải đã chạy ở opencv2.x, nó có thể được được khẳng định như sau:

import cv2 
print cv2.__version__ 

Xem opencv2.x doc

1

Nếu bạn sử dụng Python3, chèn vào 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) 

Đối với Python 2 bạn nên sử dụng

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)