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.
- A videófájl betöltése
- A jellemződetektor paramétereinek beállítása.
- Az első képkocka beolvasása ("régi képkocka")
- Minden képkockára végrehajtjuk az alábbiakat:
- a képkocka beolvasása
- a képkocka konvertálása szürkeárnyalatossá
- jellemződetektálás az aktuális képkockán
- jellemzőpontok követése
- elmozdulások kirajzolása
- 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()