Мне нужно найти оптический поток между каждыми 2 смежными кадрами видео, используя оптический поток Лукаса Канаде. Я использую python и openCV для проекта.
Насколько я понимаю, Лукас Канаде - это редкий метод поиска оптического потока. Есть ли плотная реализация этого? Если да, то как его использовать в python?
Используя cv2.calcOpticalFlowFarneback (), который является плотным методом, мы получаем в качестве вывода ndarray («поток» в примере ниже), который содержит оптический поток.
cv2.calcOpticalFlowFarneback(prev, next, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags[, flow]) → flow
Есть ли способ получить аналогичный вывод с помощью cv2.calcOpticalFlowPyrLK ()?
cv2.calcOpticalFlowPyrLK(prevImg, nextImg, prevPts[, nextPts[, status[, err[, winSize[, maxLevel[, criteria[, flags[, minEigThreshold]]]]]]]]) → nextPts, status, err
При использовании cv2.calcOpticalFlowPyrLK () (выше) полученный вывод содержит nextPts, который содержит следующие точки для отслеживания, но это не так непосредственно дать оптический поток из 2 кадров. Если я вычитаю prevPts из nextPts, получится ли оптический поток между двумя кадрами? Я нашел 'prev (y, x) ~ next (y + flow (y, x) [1], x + flow (y, x) [0]) "в разделе, объясняющем calcOpticalFlowFarneback () по этой ссылке: https://docs.opencv.org/2.4/modules/video/doc/motion_analysis_and_object_tracking.html Отсюда и вопрос. (Синтаксис для cv2.calcOpticalFlowPyrLK () и cv2.calcOpticalFlowFarneback также взят из этой ссылки) Ниже приведена моя реализация того же.
import cv2
import numpy as np
import os
import subprocess as sp
yuv_filename = 'can_0.yuv'
flow=[]
width, height = 320, 240
file_size = os.path.getsize(yuv_filename)
n_frames = file_size // (width*height*3 // 2)
f = open(yuv_filename, 'rb')
old_yuv = np.frombuffer(f.read(width*height*3//2), dtype=np.uint8).reshape((height*3//2, width))
# Convert YUV420 to Grayscale
old_gray = cv2.cvtColor(old_yuv, cv2.COLOR_YUV2GRAY_I420)
# params for ShiTomasi corner detection
feature_params = dict( maxCorners = 100,
qualityLevel = 0.3,
minDistance = 7,
blockSize = 7 )
# Parameters for lucas kanade optical flow
lk_params = dict( winSize = (15,15),
maxLevel = 2,
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)
for i in range(1,n_frames):
# Read Y, U and V color channels and reshape to height*1.5 x width numpy array
yuv = np.frombuffer(f.read(width*height*3//2), dtype=np.uint8).reshape((height*3//2, width))
# Convert YUV420 to Grayscale
gray = cv2.cvtColor(yuv, cv2.COLOR_YUV2GRAY_I420)
# calculate optical flow
p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, gray, p0, None, **lk_params)
flow.append(np.subtract(p1,p0))
good_old = p0[st==1]
good_new = p1[st==1]
# Now update the previous frame and previous points
old_gray = gray.copy()
p0 = good_new.reshape(-1,1,2)
f.close()
Поток представляет собой список ndarrays, содержащий оптический поток между соседними кадрами входного видео?
Это вывод, который я получил для потока [7] (выбран случайным образом), но я не уверен, что это значения оптического потока.
[[[6.7138672e-03 4.5318604e- 03]]
[[- 1.6220093e-02 1.9645691e-03]]
[[- 8.5296631e-03 1.8482208e-03]]
[[- 5.8441162e-03 1.5701294e-02]]
[[7.5836182e-03 2.3475647e-02]]
[[- 1.4129639e-02 1.6357422e-02]]
[[4.4555664e-03 4.1809082e-03]]
[[5.6457520e-04 -9.5863342e-03]]
[[2.8991699e-04 -3.0517578e- 05]]
[[- 2.3452759e-02 -1.5502930e-02]]
[[- 6.8283081e-03 3.3264160e-03]]
[[ -8.4381104e-03 7.7590942e-03]]
[[5.7144165e-03 1.1177063e-02]]
[[- 1.4160156e-02 2.1179199e-02]]
[[- 1.0498047e-02 8.0099106e-03]]
[[- 1.8310547e-04 2.8953552e-03]]
[[4.4937134e-03 -2.0904541 e-03]]
[[- 4.7698975e-02 3.7708282e-02]]
[[6.3323975e-03 1.3298035e-02]]
[[ -3,323364 3e-02 -1.7229080e-02]]
[[7.5683594e-03 2.4566650e-03]]
[[- 3.0364990e-03 3.4656525e-03]]
[[- 1.0345459e-02 -7.4539185e-03]]
[[1.3168335e-02 2.1423340e-02]]
[[- 6.3476562e-03 -1.0681152 e-02]]
[[1.5869141e-03 1.0375977e-03]]
[[2.1820068e-03 6.7329407e-03]]
[[- 9.6130371e-03 2.9449463e-03]]
[[- 2.1362305e-03 8.5525513e-03]]
[[- 1.7547607e-04 2.1362305e-04]]
[[2.9144287e-03 1.4343262e-03]]
[[2.9602051e-03 -7.1868896e-03]]
[[- 1.2878418e-02 5.0182343e -03]]
[[- 3.1585693e-03 -5.0544739e-05]]
[[1.0070801e-03 1.3740540e-02]]
[[ 6.7138672e-04 1.7852783e-03]]
[[- 2.0568848e-02 -1.2943268e-02]]
[[- 2.1057129e-03 4.5013428e-03]]]
Также существует ли способ получить оптический поток, используя метод Лукаса Канаде, чтобы он имел тот же размер или размеры, что и входные кадры? Если так, то как?