こんばんは。現役エンジニアの”はやぶさ”@Cpp_Learningです。
画像処理メインの研究・開発を楽しく実施しています。最近は機械学習+画像処理なPythonソフトを開発する機会が多い。。
画像ファイルだけでなく、動画ファイルやカメラの映像を処理する機会も多い。。
そのため、映像入出力の『雛形ソースコード』を作成し、「中身のアルゴリズムだけ入れ替える」という効率の良い開発を行っています。本記事では、(個人的にはとても扱いやすい)『雛形ソースコード』の開発手順を説明します。
開発手順はいらないからソースコードだけ見せてー。という人は目次から『完成したソースコード』の見出しにジャンプして下さいな。
Contents
調査と仕様検討
新規でソフトを開発するときは、必ずググって「類似ソフトはないか?」・「どんなソフトがよく使われているか?」を調査します。
また、作ったソフトをチームで共有する場合には、事前にメンバーと相談して仕様を決めておくと機能の追加が少なくて済みます。
ただし、どんなにキッチリ仕様を決めても、後から必ずカスタム要求が出てくるので、カスタムのしやすさも考慮してソフトを作っておくと後から苦労しなくて済みます。
仕様と実現方法の検討
調査・検討の結果、今回は以下の機能をもつ映像入出力に関する雛形ソースコードを作成することにしました。
【仕様】
- FPSを映像内に表示させる
- frame数を映像内に表示させる
- 任意のタイミングでソフトを中断できる
- ソフト起動時にカメラか動画ファイルどちらを扱うか選択できる
- キャプチャした映像を300×300にリサイズする
仕様が決まったら、各項目をどうやって実現するか検討します。
【実現方法の検討】
- FPSの演算にはTimerモジュールを使う
- frame数は単純なカウンターで実現可
- ソフト中断にはインターフェース入力を使う
- カメラ/動画ファイルの選択にはパーサを使う
- リサイズにはOpenCVの関数を使う
上の全項目を満たすソフトをググっても見つからないと思います。しかし、1つの項目だけ満たすソフトはきっと見つかります。
困難は分割せよ!複雑な機能や仕様も分解して、一つ一つの単機能の集合と考えれば良いのです。
単機能ごとに「調査」→「コード作成」→「テスト」を行い、最終的に複数の単機能を組み合わせた一つのソフトを開発できればOKです。
複雑な機能や仕様も分解して、一つ一つの単機能の集合と考え、単機能ごとに「調査」→「コード作成」→「テスト」を行う
カスタムのしやすさ検討
繰り返しですが、どんなにキッチリ仕様を決めても、後から必ずカスタム要求が出てくるので、カスタムのしやすさも考慮してソフトを作っておくと後から苦労しなくて済みます。
仕様の中に以下の項目があります。
- キャプチャした映像を300×300にリサイズする
「機械学習+画像処理」だと画像サイズが300×300など正方形の方が都合が良いので、こういう仕様なのですが、「元々の画像サイズはいくつなの?」と聞かれそうです。
接続したカメラのスペック表を見れば…とも思いますが、スペックの異なる複数のカメラを使って試験する場合に、いちいちスペック表を確認するのも大変です。
なので、必要なときだけキャプチャ画像のサイズを表示できるように、画像サイズを取得するコードを埋め込んでおくと親切です。
完成したソースコード
以上を踏まえ、完成したソースコード(以降 Test_Cam.py)を以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
import argparse import cv2 from timeit import default_timer as timer def main(): parser = argparse.ArgumentParser() parser.add_argument('video') args = parser.parse_args() if args.video == "0": vid = cv2.VideoCapture(0) else: vid = cv2.VideoCapture(args.video) if not vid.isOpened(): raise ImportError("Couldn't open video file or webcam.") # Compute aspect ratio of video vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH) vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT) vidar = vidw / vidh print(vidw) print(vidh) accum_time = 0 curr_fps = 0 fps = "FPS: ??" prev_time = timer() frame_count = 1 while True: ret, frame = vid.read() if ret == False: print("Done!") return # Resized im_size = (300, 300) resized = cv2.resize(frame, im_size) # ================================= # Image Preprocessing # ================================= # ================================= # Main Processing result = resized.copy() # dummy # result = frame.copy() # no resize # ================================= # Calculate FPS curr_time = timer() exec_time = curr_time - prev_time prev_time = curr_time accum_time = accum_time + exec_time curr_fps = curr_fps + 1 if accum_time > 1: accum_time = accum_time - 1 fps = "FPS:" + str(curr_fps) curr_fps = 0 # Draw FPS in top right corner cv2.rectangle(result, (250, 0), (300, 17), (0, 0, 0), -1) cv2.putText(result, fps, (255, 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1) # Draw Frame Number cv2.rectangle(result, (0, 0), (50, 17), (0, 0, 0), -1) cv2.putText(result, str(frame_count), (0, 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1) # Output Result cv2.imshow("Result", result) # Stop Processing if cv2.waitKey(1) & 0xFF == ord('q'): break frame_count += 1 if __name__ == '__main__': main() |
Test_Cam.pyの使い方
動画を使う場合は、以下のように任意の「動画ファイルパス」を設定する
python Test_Cam.py 動画ファイルパス
USBカメラ(またはノートPC内蔵のWebカメラなど)を使う場合は、動画ファイルパスの部分に”0”を設定する。
python Test_Cam.py 0
処理を中断するときは、出力映像を「マウスで左クリック」→「キーボード”Q”」で行えます。
出力映像
Test_Cam.pyを実行すると以下のような出力映像が得られます。左上がフレーム数・右上がFPSです。上部の緑色のアイコンをクリックすることで、画像の拡大・縮小や保存などの簡単な操作を行うことができます。
本記事ではOpenCV3.4.1でテストしていますが、「OpenCV => 3.0」で動くはずです。ただし、古いバージョンだと、緑色のアイコンが表示されません。
Test_Cam.pyをカスタム
Test_Cam.pyを雛形に目的に応じてカスタムを行います。
画像サイズ表示
17~22行目がキャプチャ画像サイズに関するコードです。コメントアウトしておけば、ターミナルに画像サイズが表示されます。
中身のアルゴリズム追加
40~48行目がキャプチャした画像に処理を行うコードです。今は、リサイズしたキャプチャ画像をコピーするダミー処理が入っているので、目的に応じて変更します。
まとめ
非常に簡単にですが、映像入出力の『雛形ソースコード』の開発手順を説明しました。
開発手順説明の題材は何でも良かったのですが、難しすぎず/簡単すぎず、かつ実用的な『カメラ・動画を扱うソースコード』にしました。
開発するソフトが変わっても基本的な開発手順は今回と同じです。
今後、本サイトでは、この『雛形ソースコード』をベースに様々なソフトを作る予定ですので、お楽しみに~