###実行結果
Terminal% python3 trajectory_arrow_sample_2.py --file_path f_22_fighter.mp4 --start_frame 100
Terminal% python3 trajectory_arrow_sample_2.py --file_path trump.mp4
Terminal% python3 trajectory_arrow_sample_2.py --file_path olympics_equestrian.mp4
###参考サイト
以下のウェブサイトに掲載されているPython実装を参考にしました。
参考サイトは、1本目のサイトに掲載されているコードに対して、2本目のサイトで改良を加える流れの「構成です。
1本目に掲載されているコードは、__mainメソッド__が書かれていないため、補いました。
また、2本目の訂正は、1本目のコードとどう対応関係にあるのか、わかりづらいところもありました。
メソッド間の呼び出し関係を追いかけて、__mainメソッド__ですべてが呼び出されるように補完しました。
なお、以下は新たに実装しました。
- 対象となる動画ファイルの指定: コマンドライン引数で受け取るようにしました。
- 解析を開始するフレーム番地: コマンドライン引数で受け取るようにしました (指定省略された場合はデフォルト値を適用)。
- 解析を終了するフレーム番地: 陽に明示的に指定せずに、__While True__で最終フレームまで処理するように変更。
- ウィンドウサイズ: 大きくしました。
###適宜捕捉して作成したコード
- __While Trueでループが回り続ける中で、各周で呼び出される__grabメソッド__の中で、cap.read()__が行われることで、__次のフレームの読み込み__が行われている。
trajectory_arrow_sample_2.py
import numpy as np
import cv2, types, argparse
# https://emotionexplorer.blog.fc2.com/blog-entry-104.html
# https://emotionexplorer.blog.fc2.com/blog-entry-103.html
#以下、初期化定義されないまま使われている
start_sec = 1
end_sec = 100000
# 動画ファイルをコマンドライン引数で受け取るようにする
parser = argparse.ArgumentParser(description='Motion Vector Visualization')
parser.add_argument('--file_path', type=str, help='path to movie file', required=True)
parser.add_argument('--start_frame', type=str, help='frame_step_num to be analizedanalysis', default=1)
args = parser.parse_args()
file_path = args.file_path
start_frame = int(args.start_frame)
# 縮小画像取得
def grab(cap, sc):
_, frame = cap.read()
# 画像縮小
resize_img = cv2.resize(frame, None, fx=sc, fy=sc, interpolation=cv2.INTER_CUBIC)
return resize_img
# オプティカルフロー解析描画
def drawOptFlow(img, gray, flow, step=16, dispsc=10):
cimg = img.copy()
h, w = img.shape[:2]
y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)
dx, dy = flow[y,x].T * dispsc
dist = np.sqrt(dx**2+dy**2)
idx = np.where(3 < dist)
x, y = x[idx], y[idx]
dx, dy = dx[idx], dy[idx]
lines = np.vstack([x, y, x+dx, y+dy]).T.reshape(-1, 2, 2)
lines = lines.astype(np.int32)
fx, fy = flow[y,x].T
#print(x) #x, y, dx, dyはそれぞれ行列。空行列のときもある。
#cv2.polylines(cimg, lines, False, (0, 0, 255),2)
cv2.polylines(cimg, lines, False, (255, 0, 255), 1, 8)
#cv2.arrowedLine(cimg, \
# pt1=(int(x), int(y)), \
# pt2=(int(x+dx), int(y+dy)), \
# color=(255, 0, 0),
# thickness=2,
# line_type=cv2.LINE_4,
# shift=0,
# tipLength=0.5)
return cimg
# def optflow(cap, start_sec, end_sec):
def main():
cap = cv2.VideoCapture(file_path)
if not cap.isOpened():
exit()
# 動画開始フレーム指定(1フレーム30とする)
fpos = start_frame*30+2
cap.set(cv2.CAP_PROP_POS_FRAMES, fpos)
# ShiTomasi cornerパラメータ定義
feature_params = dict( maxCorners = 100,
qualityLevel = 0.2,
minDistance = 7,
blockSize = 7 )
# lucas kanade オプティカルフローパラメータ
lk_params = dict( winSize = (30,30),
maxLevel = 2,
criteria=(cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_COUNT, 10, 0.03))
###以上、1本目のサイトのmain()から移植
###以下、2本目のサイトのoptflow()から移植
# 色
color = np.random.randint(0,255,(100,3))
# 縮小画像取得
frame1 = grab(cap, 0.5)
prvs = cv2.cvtColor(frame1,cv2.COLOR_BGR2GRAY)
# 動画開始フレーム指定
fpos = 30 * start_sec
cap.set(cv2.CAP_PROP_POS_FRAMES, fpos)
hsv = np.zeros_like(frame1)
hsv[...,1] = 255
# loopend = (end_sec - start_sec) * 30
# for j in range(0, loopend):
# While Trueに変更
while True:
# 縮小画像取得
frame2 = grab(cap, 0.5)
next = cv2.cvtColor(frame2,cv2.COLOR_BGR2GRAY)
# オプティカルフロー解析
flow = cv2.calcOpticalFlowFarneback(prvs,next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
# オプティカルフロー解析描画
rgb2 = drawOptFlow(frame2, next, flow, 16)
# ウィンドウのサイズが小さいので、大きくする
height = rgb2.shape[0]
width = rgb2.shape[1]
resized_output_img = cv2.resize(rgb2, (int(3.0*width), int(3.0*height)))
cv2.namedWindow("Video", cv2.WINDOW_NORMAL)
cv2.imshow("Video", resized_output_img)
# オプティカルフロー解析描画
#cv2.imshow('Display',rgb2)
# ESCキー押下で終了
k = cv2.waitKey(30) & 0xff
if k == 27:
break
prvs = next
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
###動画データ取得
Terminal
% youtube-dl -F https://youtu.be/1oRWaLgilds
[youtube] 1oRWaLgilds: Downloading webpage
[info] Available formats for 1oRWaLgilds:
format code extension resolution note
249 webm audio only tiny 52k , webm_dash container, opus @ 52k (48000Hz), 494.11KiB
250 webm audio only tiny 69k , webm_dash container, opus @ 69k (48000Hz), 658.19KiB
140 m4a audio only tiny 129k , m4a_dash container, mp4a.40.2@129k (44100Hz), 1.20MiB
251 webm audio only tiny 136k , webm_dash container, opus @136k (48000Hz), 1.27MiB
278 webm 256x144 144p 92k , webm_dash container, vp9@ 92k, 30fps, video only, 873.04KiB
160 mp4 256x144 144p 101k , mp4_dash container, avc1.4d400c@ 101k, 30fps, video only, 962.21KiB
242 webm 426x240 240p 183k , webm_dash container, vp9@ 183k, 30fps, video only, 1.70MiB
133 mp4 426x240 240p 224k , mp4_dash container, avc1.4d4015@ 224k, 30fps, video only, 2.08MiB
243 webm 640x360 360p 320k , webm_dash container, vp9@ 320k, 30fps, video only, 2.97MiB
134 mp4 640x360 360p 472k , mp4_dash container, avc1.4d401e@ 472k, 30fps, video only, 4.37MiB
244 webm 854x480 480p 558k , webm_dash container, vp9@ 558k, 30fps, video only, 5.17MiB
135 mp4 854x480 480p 872k , mp4_dash container, avc1.4d401f@ 872k, 30fps, video only, 8.07MiB
247 webm 1280x720 720p 1073k , webm_dash container, vp9@1073k, 30fps, video only, 9.93MiB
136 mp4 1280x720 720p 1659k , mp4_dash container, avc1.64001f@1659k, 30fps, video only, 15.35MiB
248 webm 1920x1080 1080p 1801k , webm_dash container, vp9@1801k, 30fps, video only, 16.66MiB
137 mp4 1920x1080 1080p 3226k , mp4_dash container, avc1.640028@3226k, 30fps, video only, 29.85MiB
18 mp4 640x360 360p 567k , avc1.42001E, 30fps, mp4a.40.2 (44100Hz), 5.25MiB
22 mp4 1280x720 720p 1791k , avc1.64001F, 30fps, mp4a.40.2 (44100Hz) (best)
%
% youtube-dl -f22 https://youtu.be/1oRWaLgilds
[youtube] 1oRWaLgilds: Downloading webpage
[download] Destination: 東京五輪 競技解説動画~馬術編-1oRWaLgilds.mp4
[download] 100% of 16.58MiB in 00:00
% ls
doraemon.mp4 trump.mp4
requirements.txt yolo3_movie.py
trajectory_arrow_sample_1.py yolo3_movie2.py
trajectory_arrow_sample_2.py 東京五輪 競技解説動画~馬術編-1oRWaLgilds.mp4
%
% mv '東京五輪 競技解説動画~馬術編-1oRWaLgilds.mp4' olympics_equestrian.mp4
% ls
doraemon.mp4 requirements.txt trajectory_arrow_sample_2.py yolo3_movie.py
olympics_equestrian.mp4 trajectory_arrow_sample_1.py trump.mp4 yolo3_movie2.py
%
% open olympics_equestrian.mp4
Terminal
% youtube-dl -F https://youtu.be/jteHodCNqSI
[youtube] jteHodCNqSI: Downloading webpage
[info] Available formats for jteHodCNqSI:
format code extension resolution note
249 webm audio only tiny 46k , webm_dash container, opus @ 46k (48000Hz), 3.53MiB
250 webm audio only tiny 62k , webm_dash container, opus @ 62k (48000Hz), 4.73MiB
251 webm audio only tiny 126k , webm_dash container, opus @126k (48000Hz), 9.54MiB
140 m4a audio only tiny 129k , m4a_dash container, mp4a.40.2@129k (44100Hz), 9.80MiB
160 mp4 256x144 144p 27k , mp4_dash container, avc1.4d400c@ 27k, 30fps, video only, 2.12MiB
278 webm 256x144 144p 56k , webm_dash container, vp9@ 56k, 30fps, video only, 4.27MiB
242 webm 426x240 240p 61k , webm_dash container, vp9@ 61k, 30fps, video only, 4.61MiB
133 mp4 426x240 240p 74k , mp4_dash container, avc1.4d4015@ 74k, 30fps, video only, 5.61MiB
243 webm 640x360 360p 144k , webm_dash container, vp9@ 144k, 30fps, video only, 10.94MiB
134 mp4 640x360 360p 152k , mp4_dash container, avc1.4d401e@ 152k, 30fps, video only, 11.55MiB
244 webm 854x480 480p 227k , webm_dash container, vp9@ 227k, 30fps, video only, 17.23MiB
135 mp4 854x480 480p 239k , mp4_dash container, avc1.4d401f@ 239k, 30fps, video only, 18.14MiB
247 webm 1280x720 720p 373k , webm_dash container, vp9@ 373k, 30fps, video only, 28.22MiB
136 mp4 1280x720 720p 403k , mp4_dash container, avc1.4d401f@ 403k, 30fps, video only, 30.54MiB
18 mp4 640x360 360p 363k , avc1.42001E, 30fps, mp4a.40.2 (44100Hz), 27.53MiB
22 mp4 1280x720 720p 532k , avc1.64001F, 30fps, mp4a.40.2 (44100Hz) (best)
%
Terminal
% youtube-dl -f 22 https://youtu.be/jteHodCNqSI
[youtube] jteHodCNqSI: Downloading webpage
[download] Destination: ステルス戦闘機F-22ラプターの凄い機動力のアクロバット・デモ飛行-jteHodCNqSI.mp4
[download] 100% of 40.29MiB in 00:07
%
Terminal
% mv 'ステルス戦闘機F-22ラプターの凄い機動力のアクロバット・デモ飛行-jteHodCNqSI.mp4' f_22_fighter.mp4
ls
doraemon.mp4 requirements.txt trump.mp4
f_22_fighter.mp4 trajectory_arrow_sample_1.py yolo3_movie.py
olympics_equestrian.mp4 trajectory_arrow_sample_2.py yolo3_movie2.py
%