「喰う・書く・逃げる」に棲む処

 動物に関するデータ分析者のブログです

OpenCVで動画を逆再生、逆再生しながらコマ送りしてみる

OpenCVで動画を逆再生してみました。

OpenCVの関数'VideoCapture.read()'だと順方向にしか再生できないので何度も'VideoCapture'をリリースして再びビデオを読み込むというアプローチをとっています。

この方法だとCPUのシングルスレッド性能に依存するでしょうね。コマ送りにしてみるともっさり感が増します。もしかしたら、メモリにすべてのフレームを書き込んでしまう方がいいかもしれません。でも長い動画になってくると今度はメモリ不足みたいなことになるかもしれませんね。

逆再生プログラム

import cv2

def main():
    videoPath: str = "動画ファイル"
    delay: int =  1 #mm

    #映像の読み込み
    srcVideo: cv2.VideoCapture = cv2.VideoCapture(videoPath)
    frameNum: int = srcVideo.get(cv2.CAP_PROP_FRAME_COUNT)-1

    #映像フレームの読み込みに使う変数の宣言
    retval: bool
    srcFrame: cv2.Mat
    
    #ウインドウの生成
    cv2.namedWindow("video",cv2.WINDOW_KEEPRATIO)
    
    #映像の表示
    if srcVideo.isOpened():
        
        #後ろのフレーム読み込み
        srcVideo.set(cv2.CAP_PROP_POS_FRAMES,frameNum)
        retval, srcFrame = srcVideo.read()
        
        while True:
            if retval:
                #表示
                cv2.imshow("video",srcFrame)
                pressedKey = cv2.waitKey(delay)
                #表示する駒を前に進める
                frameNum -= 1
            if frameNum == 0 or (pressedKey & 0xFF == ord('q')):
                #フレームが一番前まで到達もしくは"Qボタンを押したら"ループから抜ける
                break
            else:
                #一旦リリースしてから動画を再読み込み
                srcVideo.release()
                srcVideo = cv2.VideoCapture(videoPath)
                #フレームの読み込み
                srcVideo.set(cv2.CAP_PROP_POS_FRAMES,frameNum)
                retval, srcFrame = srcVideo.read()
        
    srcVideo.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

逆再生コマ送りするなら以下の部分を

        while True:
            if retval:
                #表示
                cv2.imshow("video",srcFrame)
                pressedKey = cv2.waitKey(delay)
                #表示する駒を前に進める
                frameNum -= 1
            if frameNum == 0 or (pressedKey & 0xFF == ord('q')):
                #フレームが一番前まで到達もしくは"Qボタンを押したら"ループから抜ける
                break
            else:
                #一旦リリースしてから動画を再読み込み
                srcVideo.release()
                srcVideo = cv2.VideoCapture(videoPath)
                #フレームの読み込み
                srcVideo.set(cv2.CAP_PROP_POS_FRAMES,frameNum)
                retval, srcFrame = srcVideo.read()

以下のように変更すると左矢印十字キーで逆再生コマ送りになります。

        while True:
            if retval:
                #表示
                cv2.imshow("video",srcFrame)
                pressedKey = cv2.waitKeyEx(delay)
                if pressedKey == 2424832:              #左矢印十字キー
                    frameNum -= 1
                    #一旦リリースしてから動画を再読み込み
                    srcVideo.release()
                    srcVideo = cv2.VideoCapture(videoPath)
                    #フレームの読み込み
                    srcVideo.set(cv2.CAP_PROP_POS_FRAMES,frameNum)
                    retval, srcFrame = srcVideo.read()
            if frameNum == 0 or (pressedKey & 0xFF == ord('q')):
                #フレームが一番前まで到達もしくは"Qボタンを押したら"ループから抜ける
                break