0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SitarHarmonicsさんが書いた物体の動きを可視化するコードを復元して、戦闘機と馬術競技のMP4動画で試した(成功)

Last updated at Posted at 2021-08-12

###実行結果

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
%
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?