Optical Flow on Python

Kategori: Computer Vision , 01 Mart 2020 , JanFranco


Bir önceki yazımızda Optical Flow algoritmasını anlatmıştım. Bu yazıda ise OpenCV kütüphanesi ile Optical Flow örneği yapacağız. OpenCV kütüphanesinde Optical Flow algoritması için calcOpticalFlowPyrLK methodu bulunuyor. Methodun parametrelerini görelim:

cv2.calcOpticalFlowPyrLK(prevImg, nextImg, prevPts, nextPts, status, err, winSize, maxLevel, criteria, flags, minEigThreshold)

prevImg - t zamanındaki input görüntü, frame
nextImg - t + 1 zamanındaki input görüntü, frame
prevPts - Takip edilecek nokta/noktalar
nextPts - Track edilen noktaların nereye yazılacağı, (kullanmayacağız)
status - Akış bulunursa method 1 return edecek. Bunu bu parametre ile değiştirebiliriz (kullanmayacağız)
err - status parametresine benzer, hata parametresi.
(kullanmayacağız) winSize - Her bir pyramid leveldeki pencere boyutu (açıklayacağım)
maxLevel - Pyramid'in max seviyesi (açıklayacağım)
criteria - OpenCV algoritmaları ile ilgilidir.
criteria.maxCount maximum iteration sayısını, criteria.epsilon oluşturulan pencerenin limit hareketidir. Eğer iteration sayısı maxCount'u geçerse veya window epsilon değerinden daha düşük bir değerde hareket ederse algoritma, fonksiyon sonlanır.
flags - -
minEigThreshold - Minimum (u, v) vektör değeri. (kullanmayacağız)

Örneği bir video üzerinden yapacağız. Videoyu aşağıdaki linkten indirebilirsiniz:

https://www.bogotobogo.com/python/OpenCV_Python/images/mean_shift_tracking/slow_traffic_small.mp4

Video path yerine tırnaksız 0 yazarak kameradan da çalıştırabiliriz. O şekilde de deneyebilirsiniz. Kütüphaneleri, videoyu alalım ve fonksiyon parametlerini tanımlayalım:


import cv2
import numpy as np

corner_track_params = dict(maxCorners=10, qualityLevel=0.3, minDistance=7, blockSize=5)
lk_params = dict(winSize=(200, 200), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

cap = cv2.VideoCapture('../data/traffic.mp4')
Burada takip edeceğimiz noktaları belirlemek için goodFeatureToTrack methodunu kullanacağız. Daha önceki yazılarımda nasıl kullanılacağını ve algoritmasını anlatmıştım. İlk olarak while döngüsünden önce noktaları belirleyelim:


_, prev_frame = cap.read()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
prevPts = cv2.goodFeaturesToTrack(prev_gray, mask=None, **corner_track_params)
mask = np.zeros_like(prev_frame)
mask değişkenine boş bir image atadık. Bu image'a çizeceğimiz çizgileri yazacağız. While döngüsünü açalım, frame frame okuyalım. Her bir frame'ı grayscale hale çevirelim. cv2.calcOpticalFlowPyrLK() methodu ile next pointleri nextPts değişkenine atalım. Eğer takip edebilirsek cv2.calcOpticalFlowPyrLK() methodu 1 return edecektir. Bu özelliği kullanarak nextPts ve prevPts değişkenlerindeki noktaları alarak çizgi çizelim. Böylelikle tracking'i de görebiliriz. Ayrıca noktaların olduğu yerde de circle methodu ile daireler çizelim:


while True:

    _, frame = cap.read()
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    nextPts, status, err = cv2.calcOpticalFlowPyrLK(prev_gray, frame_gray, prevPts, None, **lk_params)
    good_new = nextPts[status == 1]
    good_prev = prevPts[status == 1]

    for i, (new, prev) in enumerate(zip(good_new, good_prev)):
        x_new, y_new = new.ravel()
        x_prev, y_prev = prev.ravel()
        mask = cv2.line(mask, (x_new, y_new), (x_prev, y_prev), (0, 255, 0), 3)
        frame = cv2.circle(frame, (x_new, y_new), 5, (0, 0, 255), -1)

    img = cv2.add(frame, mask)
    cv2.imshow('frame', img)

    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

    prev_gray = frame_gray.copy()
    prevPts = good_new.reshape(-1, 1, 2)

cv2.destroyAllWindows()
cap.release()
>>




Sonraki Yazı: Object Tracking - Meanshift
Yorumlar

Henüz bir yorum bulunmuyor.
Yorum bırakın