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

###実行結果

>```bash:Terminal
>% python3 trajectory_arrow_sample_2.py --file_path f_22_fighter.mp4 --start_frame 100 
>```

![](https://user-images.githubusercontent.com/87643752/129235872-940e84c9-5208-45e1-8608-fa622bfbe7c9.png)

![](https://user-images.githubusercontent.com/87643752/129235934-d2f76079-4bef-4704-b4f5-1d7e45f3fe53.png)

![](https://user-images.githubusercontent.com/87643752/129236045-78254f55-b2cf-4a43-85b3-360d35372c21.png)

![](https://user-images.githubusercontent.com/87643752/129236100-4f345636-2ddb-4700-bc43-3c65865bb16e.png)

>```bash:Terminal
>% python3 trajectory_arrow_sample_2.py --file_path trump.mp4
>```

![](https://user-images.githubusercontent.com/87643752/129236234-0131f53e-a43c-4600-84ea-99c0252126bb.png)

![](https://user-images.githubusercontent.com/87643752/129236642-faddb490-3b3f-4cac-852b-322d502dfb11.png)

![](https://user-images.githubusercontent.com/87643752/129236657-24e1565c-b8e0-46e1-98f0-f25730a88be6.png)

>```bash:Terminal
>% python3 trajectory_arrow_sample_2.py --file_path olympics_equestrian.mp4
>```

![](https://user-images.githubusercontent.com/87643752/129236457-97493945-c47b-4823-80dc-fc579275eac0.png)

###参考サイト

以下のウェブサイトに掲載されているPython実装を参考にしました。

- [OpenCV　オプティカルフロー](https://emotionexplorer.blog.fc2.com/blog-entry-104.html)
- [OpenCV　オプティカルフロー（２）](https://emotionexplorer.blog.fc2.com/blog-entry-103.html)

参考サイトは、１本目のサイトに掲載されているコードに対して、2本目のサイトで改良を加える流れの「構成です。
1本目に掲載されているコードは、__*main*メソッド__が書かれていないため、補いました。

また、2本目の訂正は、1本目のコードとどう対応関係にあるのか、わかりづらいところもありました。
メソッド間の呼び出し関係を追いかけて、__mainメソッド__ですべてが呼び出されるように補完しました。

なお、以下は新たに実装しました。

- 対象となる動画ファイルの指定： コマンドライン引数で受け取るようにしました。
- 解析を開始するフレーム番地： コマンドライン引数で受け取るようにしました （指定省略された場合はデフォルト値を適用）。
- 解析を終了するフレーム番地： 陽に明示的に指定せずに、__*While True*__で最終フレームまで処理するように変更。
- ウィンドウサイズ： 大きくしました。


###適宜捕捉して作成したコード

- __*While True*__でループが回り続ける中で、各周で呼び出される__grabメソッド__の中で、__*cap.read()*__が行われることで、__次のフレームの読み込み__が行われている。

```Python3: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))
                    
    ###以上、１本目のサイトのmain()から移植
    ###以下、２本目のサイトの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()

```

###動画データ取得

```bash: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 
```



```bash: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)
% 
```

```bash: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
% 
```


```bash: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
%
```