Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

Dear PyGuiとOpenCVを組み合わせて動画再生アプリを作成してみる

前回はDear PyGuiというpython用のGUIライブラリについてご紹介しました。
elsammit-beginnerblg.hatenablog.com

今回はこちらのDear PyGuiとOpenCVを組み合わせて動画再生アプリを作成してみたいと思います。



■Dear PyGui上で動画を表示してみる

では早速Dear PyGuiとOpenCVを組み合わせて動画表示方法についてまとめていきます。
まずはコードを載せます。

import dearpygui.dearpygui as dpg
import numpy as np
import cv2
import time

dpg.create_context()
dpg.create_viewport(max_width=550, max_height=360)
dpg.setup_dearpygui()

VideoFile = "X:\StudyCode\python\Forest - 49981.mp4"

vid = cv2.VideoCapture(VideoFile)
ret, img = vid.read()
frame_rate = int(vid.get(cv2.CAP_PROP_FPS))
img = cv2.resize(img , (480, 270))

with dpg.texture_registry(show=False):
    dpg.add_raw_texture(480, 270, img, tag="texture_tag", format=dpg.mvFormat_Float_rgb, use_internal_label=False)

with dpg.window(label="Main window",pos=[10,10]):
    dpg.add_image("texture_tag")

dpg.show_viewport()

while dpg.is_dearpygui_running():
    ret, img = vid.read()
    if ret == True:
        img = cv2.resize(img , (480, 270))
        data = np.flip(img, 2)
        data = data.ravel()
        data = np.asfarray(data, dtype='f')
        texture_data = np.true_divide(data, 255.0)
            
        dpg.set_value("texture_tag", texture_data)

        time.sleep(1/frame_rate)
    else:
        vid.release()
        vid = cv2.VideoCapture(VideoFile)

    dpg.render_dearpygui_frame()

dpg.destroy_context()

解説ですが、、、

dpg.create_context()
dpg.create_viewport(max_width=550, max_height=360)
dpg.setup_dearpygui()

はDear PyGuiでGUI Windowのセットアップを行うためのコードになり、

VideoFile = "動画path"
vid = cv2.VideoCapture(VideoFile)
ret, img = vid.read()
frame_rate = int(vid.get(cv2.CAP_PROP_FPS))
img = cv2.resize(img , (480, 270))

OpenCVによる動画データ読み出し処理になります。

ここまでは一般的な処理になりますね。

GUI Windowの定義ですが、

with dpg.window(label="Main window",pos=[10,10]):
    dpg.add_image("texture_tag")

としており、imageを追加しているのみになり、タブ名をtexture_tagとしています。
このtexture_tagに表示する画像データを定義しているのは、

with dpg.texture_registry(show=False):
    dpg.add_raw_texture(480, 270, texture_data, tag="texture_tag", format=dpg.mvFormat_Float_rgb, use_internal_label=False)

になります。

add_raw_texture APIはimage領域に画像データをセットする関数になります。
今回は、texture_tag名のimage領域にtexture_dataをセットします。
texture_dataですが、こちらのコードにてOpenCVで読み出したフレーム画像を
numpyにより変換を行った結果が格納しております。

data = np.flip(img, 2) 
data = data.ravel()
data = np.asfarray(data, dtype='f')
texture_data = np.true_divide(data, 255.0)

最後に、、、

while dpg.is_dearpygui_running():
    ret, img = vid.read()
    if ret == True:
        img = cv2.resize(img , (480, 270))
        data = np.flip(img, 2)
        data = data.ravel()
        data = np.asfarray(data, dtype='f')
        texture_data = np.true_divide(data, 255.0)
            
        dpg.set_value("texture_tag", texture_data)

        time.sleep(1/frame_rate)
    else:
        vid.release()
        vid = cv2.VideoCapture(VideoFile)

    dpg.render_dearpygui_frame()

にて、OpenCVで1フレーム毎に読み出し、先ほどの通りnumpyにより配列変換を行った上でtexture_tagにセット。

ループ再生にしておきたかったので、

    else:
        vid.release()
        vid = cv2.VideoCapture(VideoFile)

により、動画データのフレームが読み出せなくなったら再度動画データを読み出し、フレームの読み出しを繰り返していきます。

こちらのアプリを実行するとこちらの通り、動画再生が行われます。
f:id:Elsammit:20211230145820g:plain

■動画再生アプリのご紹介

先ほどのコードは動画がただ再生されるのみのコードになります。
ちょっとそれだけでは寂しいので、、、
こちらの機能を追加した動画再生アプリを作成してみました!!
 ・動画一時停止
 ・動画種類として、赤外や2値画像に切替処理
 ・再生する動画の変更

アプリ動作はyoutubeにて投稿してみましたのでよかったらご覧ください。
youtu.be

また、コードはこちらに格納してみました。
詳しい解説はもしかしたら後ほど投稿するかもです!!
GitHub - Elsammit/PlayMovie_CreatedInDearPy

■最後に

今回はDear PyGuiとOpenCVを組み合わせて動画再生アプリを作成してみました。
Dear PyGui、結構簡単にGUIアプリ作成できるのでお勧めです!!