2017-04-19 3 views
1

tout d'abord, je suis nouveau à la programmation, mais je voudrais apprendre surtout python. mon expérience en animation et CGI.Extrait flux optique que des données (nombres) de flux en direct (webcam) en utilisant Python openCV

J'ai python 2.7 et openCV x64 installés sur Windows. J'ai testé l'exemple de flux optique qu'ils ont (opt_flow.py) (les flèches vertes) j'aime cela, mais j'essaie de comprendre comment je peux obtenir les données comme valeurs. Je ne suis pas intéressé à voir la sortie de la caméra ou les flèches vertes Je veux juste que les données soient utilisées plus tard. Y at-il un moyen de le faire? par exemple: la valeur de x, y et la longueur des flèches vertes.

Merci à tous

Répondre

2

Vous pouvez obtenir les vecteurs de flux optique (flèches vertes) dans la fonction draw_flow de opt_flow.py. Voici comment je le ferais:

#!/usr/bin/env python 

''' 
example to show optical flow 

USAGE: opt_flow.py [<video_source>] 

Keys: 
1 - toggle HSV flow visualization 
2 - toggle glitch 

Keys: 
    ESC - exit 
''' 

# Python 2/3 compatibility 
from __future__ import print_function 

import numpy as np 
import math 
import cv2 
import video 


def draw_flow(img, flow, step=16): 
    global arrows 
    h, w = img.shape[:2] 
    y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int) 
    fx, fy = flow[y,x].T 
    lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2) 
    lines = np.int32(lines + 0.5) 
    vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) 
    cv2.polylines(vis, lines, 0, (0, 255, 0)) 
    for (x1, y1), (x2, y2) in lines: 
     arrows.append([x1,y1, math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))]) 
     cv2.circle(vis, (x1, y1), 1, (0, 255, 0), -1) 
    return vis 


def draw_hsv(flow): 
    h, w = flow.shape[:2] 
    fx, fy = flow[:,:,0], flow[:,:,1] 
    ang = np.arctan2(fy, fx) + np.pi 
    v = np.sqrt(fx*fx+fy*fy) 
    hsv = np.zeros((h, w, 3), np.uint8) 
    hsv[...,0] = ang*(180/np.pi/2) 
    hsv[...,1] = 255 
    hsv[...,2] = np.minimum(v*4, 255) 
    bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) 
    return bgr 


def warp_flow(img, flow): 
    h, w = flow.shape[:2] 
    flow = -flow 
    flow[:,:,0] += np.arange(w) 
    flow[:,:,1] += np.arange(h)[:,np.newaxis] 
    res = cv2.remap(img, flow, None, cv2.INTER_LINEAR) 
    return res 

if __name__ == '__main__': 
    import sys 
    print(__doc__) 
    try: 
     fn = sys.argv[1] 
    except IndexError: 
     fn = 0 

    arrows = [] 
    cam = video.create_capture(fn) 
    ret, prev = cam.read() 
    prevgray = cv2.cvtColor(prev, cv2.COLOR_BGR2GRAY) 
    show_hsv = False 
    show_glitch = False 
    cur_glitch = prev.copy() 

    while True: 
     ret, img = cam.read() 
     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
     flow = cv2.calcOpticalFlowFarneback(prevgray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0) 
     prevgray = gray 

     arrows.clear() 
     finalImg = draw_flow(gray,flow) 
     print(arrows) 
     cv2.imshow('flow', finalImg) 
     if show_hsv: 
      cv2.imshow('flow HSV', draw_hsv(flow)) 
     if show_glitch: 
      cur_glitch = warp_flow(cur_glitch, flow) 
      cv2.imshow('glitch', cur_glitch) 

     ch = cv2.waitKey(5) 
     if ch == 27: 
      break 
     if ch == ord('1'): 
      show_hsv = not show_hsv 
      print('HSV flow visualization is', ['off', 'on'][show_hsv]) 
     if ch == ord('2'): 
      show_glitch = not show_glitch 
      if show_glitch: 
       cur_glitch = img.copy() 
      print('glitch is', ['off', 'on'][show_glitch]) 
    cv2.destroyAllWindows() 

Dans le code ci-dessus, je sauve les vecteurs de flux optique (début coordonnées du point et la longueur du vecteur) dans la comme variable globale arrows donc:

arrows.append([x1,y1, math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))]) 

avec (x1, y1) le point de départ de la flèche et (x2, y2) le point final de la flèche.

Espérons que ça aide.

+0

Tout d'abord, merci beaucoup @Elouarn, c'est ce que je veux. J'ai essayé sur python shell je peux voir toutes les données sortent (même si c'était lourd). Depuis que je suis nouveau à la programmation, je pourrais vous déranger avec quelques choses de plus. Premièrement: je voulais ces valeurs afin que je puisse l'appeler plus tard dans une bibliothèque différente comme PyOpenGL la question est comment appeler chaque valeur séparément? arrow.x1 ou arrow.length ... ainsi de suite. –

+0

Pour accéder à chaque valeur séparément, vous pouvez parcourir le tableau 'flows' avec une boucle' for'. Pour imprimer uniquement 'x1', vous pouvez faire quelque chose comme' pour [x1, y1, length] dans les flèches: print (x1) 'ou' pour les flèches dans les flèches: print (arrow [0]) '. J'espère que c'est ce que vous demandiez! Si ma réponse vous a aidé, pensez à l'accepter :) –

+0

Merci, encore une fois c'est ce que je cherche. maintenant ma deuxième question: si je veux utiliser ces valeurs par exemple dans openGL je dirais par exemple organiser tous ces objets X value par 'arrow [0]' ou utiliser la valeur Z de 'arrow [3]' ... Am J'ai raison? . (désolé je suis nouveau ici je viens de voir la partie de réponse d'acceptation, je l'ai fait maintenant) merci beaucoup :) –