Skip navigation

Pontkövetés és optikai áramlás OpenCV-ben

Példa

Az alábbiakban egy egyszerű program segítségével áttekintjük, hogy hogyan lehet OpenCV-ben meghatározni az optikai áramlást. A példaprogram az OpenCV függvénykönyvtár példája alapján lett átdolgozva. Ez a példa a Shi-Tomasi sarokdetektort használja a jellemzőpontok meghatározásához és a Lucas-Kanade algoritmust az optikai áramlás meghatározásához.

  1. A videófájl betöltése
  2. A jellemződetektor paramétereinek beállítása.
  3. Az első képkocka beolvasása ("régi képkocka")
  4. Minden képkockára végrehajtjuk az alábbiakat:
    1. a képkocka beolvasása
    2. a képkocka konvertálása szürkeárnyalatossá
    3. jellemződetektálás az aktuális képkockán
    4. jellemzőpontok követése
    5. elmozdulások kirajzolása
    6. a régi képkocka tartalmának frissítése az aktuális képkockára

A példát az alábbi videófájlon hajtjuk végre:

import numpy as np
import cv2
from matplotlib import pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()

## Videófájl megnyitása
cap = cv2.VideoCapture('../vonat1.mp4')

## Kodek beállítása a videóíráshoz
fourcc = cv2.VideoWriter_fourcc(*'XVID')
 
out = cv2.VideoWriter('optflow.avi',fourcc, 20.0, (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))) )

## A Shi-Tomasi sarokdetektor paramétereinek megadása
feature_params = dict( maxCorners = 100,
                       qualityLevel = 0.3,
                       minDistance = 7,
                       blockSize = 7 )
## A Lucas-Kanade optikai áramlás algoritmus paramétereinek beállítása
lk_params = dict( winSize  = (15,15),
                  maxLevel = 2,
                  criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
## Egy véletlenszerű szín beállítása
color = np.random.randint(0,255,(100,3))

## Az első képkocka beolvasása
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)

## Maszk készítése a rajzoláshoz
mask = np.zeros_like(old_frame)



while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:
        
    
        frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
        p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)
        ## Az optikai áramlás számolása
        p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
        ## A jól követhető pontok kiválasztása
        good_new = p1[st==1]
        good_old = p0[st==1]
        ## követet pontok elmozdulásainak kirajzolása
        for i,(new,old) in enumerate(zip(good_new,good_old)):
            a,b = new.ravel()
            c,d = old.ravel()
            mask = cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)    
            frame = cv2.circle(frame,(a,b),5,color[i].tolist(),-1)
        img = cv2.add(frame,mask)
  
        out.write(img)
        old_gray = frame_gray

    else:
        break

# videófeldolgozás lezárása
cap.release()
out.release()