アジェンダ
- はじめに
- 出来上がったツールのデモ
- openCVで動画解析
- wxpythonでGUI作成
- pyinstallerでexe化
はじめに
動画中の「どの時間に」「どんな人物がでてくるか」を知りたいって思ったことがあって、
勉強していたwxpythonとopenCVでシンプルな動画解析ツールを作成してみました。
自分用のメモも兼ねて、ここで紹介させていただきます。
ダウンロードはこちらから
GitLab ChuntaMovieAnalyzer
出来上がったツールのデモ
まずはツールのデモ画面から。
動画を指定してhtmlのレポートを出力します。
動画の秒数ごとに人間の顔を抽出して表示しています。
GUIで秒数の間隔や抽出する最大人数を変更できます。
ダウンロードはこちらから
GitLab ChuntaMovieAnalyzer
openCVで動画解析
動画を解析する際に利用したライブラリはopenCVです。
今回は動画の1フレームを画像データにし、
画像データから顔を検出し、トリミングしています。
トリミングしたデータはhtml用の画像として出力しています。
ポイントと思われる部分のコードについて紹介します。
動画を読み込んで画像を出力
動画を読み込んで、動画の総フレーム数とfps(1秒あたりのフレーム数)を利用し、指定された秒数の間隔ごとに処理を行っています。
def get_sampling_data_list(self, movie_path, report_path, interval_time, max_human, is_advance):
sampling_data_list = []
cap = cv2.VideoCapture(movie_path)
if not cap.isOpened():
print('cannot open movie file.')
return []
# 総フレーム数を取得
all_frame_cnt = cap.get(cv2.CAP_PROP_FRAME_COUNT)
# フレームレートからサンプリングするフレーム数を算出
fps = cap.get(cv2.CAP_PROP_FPS)
sampling_frame_num = math.floor( fps * interval_time )
frame_cnt = 1
while True:
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_cnt)
ret, frame = cap.read()
if ret:
sampling_data = self.get_sampling_data(frame, frame_cnt, fps, report_path, max_human, is_advance)
sampling_data_list.append(sampling_data)
frame_cnt = frame_cnt + sampling_frame_num
else:
break
return sampling_data_list
1フレームごとの処理
1フレームを画像データ化 ⇒ 画像データから顔を検出 ⇒ トリミング ⇒ html用の画像として出力
の順で処理を行っています。
def get_sampling_data(self, frame, frame_cnt, fps, report_path, max_human, is_advance):
data = sampling_data(frame_cnt, fps)
face_cascade = cv2.CascadeClassifier(resourcePath('cascade/haarcascade_frontalface_default.xml'))
src_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faceInfoList = face_cascade.detectMultiScale(src_gray)
human_cnt = 0
for x, y, w, h in faceInfoList:
# 最大人数を超えている場合はループを抜ける
if human_cnt >= max_human:
break
# トリミング
img_trim = frame[y:(y + h), x:(x + w)]
data2 = None
data2 = human_data()
# 画像出力用フォルダを作成
if False == os.path.exists(report_path + '/img'):
os.mkdir(report_path + '/img')
# 画像出力
file_name = str(frame_cnt) + '_' + str(human_cnt) + '.jpg'
cv2.imwrite(report_path + '/img/' + file_name, img_trim)
data2.set_img_src(report_path, file_name)
data.append_human_data(data2)
human_cnt = human_cnt + 1
return data
wxpythonでGUI作成
GUI部分のソースです。
ポイントと思われる部分のコードについて紹介します。
動画解析処理呼び出し処理
動画解析処理は時間がかかるため、非同期で呼び出さないとビジー状態になってしまいます。
これを回避するために、呼び出し部分は非同期にしています。
import threading
# 処理に時間がかかり画面がフリーズするのを防ぐためにスレッドキックする
analysis_thread = threading.Thread(target=exec_analyze, args=(self.analysis, self.btn, movie_path, interval_time, max_human, is_advance, token, report_path))
analysis_thread.start()
def exec_analyze(analysis, btn, movie_path, interval_time, max_human, is_advance, token, report_path):
analysis.analyze(movie_path, int(interval_time), int(max_human), is_advance, token, report_path)
wx.MessageBox('指定されたフォルダにhtmlファイルを出力しました。', '処理完了')
exe化
exe化する際はpyinstallerを利用しました。
外部リソースをexeに同封する際はひと工夫必要でした。
下記のサイトを参考に実施しました。
参考にしたURL
Pyinstaller でリソースを含めたexeを作成する
コマンドプロンプトで下記を実行
pyinstaller --onefile --icon=icon.ico -n chuntaMovieAnalyzer view_gui.py
作成されたspecファイルを編集し、再度コマンドプロンプトで下記を実行
pyinstaller chuntaMovieAnalyzer.spec
ダウンロードはこちらから
GitLab ChuntaMovieAnalyzer