はじめに
こんにちは。犬です。
...という事で(脈絡無視)、今回はタイトル通りのプログラムを書いてみました。
モチベーション
私は所属大学のゼミで、歩容認証やそれを活かした個人認証、そしてスポーツシーンへの転用を考えた研究をしています。スポーツシーンのみならず、様々なシーンでの認証には動画データが必要で、これ(入力)が無いと私の研究は始まりません。
そういうわけで、今回は「PCで細かく動画データを取得(撮影)できるプログラム」を書こうと思いました。
使うもの
①Python 3.7.6 ... JupyterNotebookで実行しました。
②opencv 4.3.0 ... ①上で使用しました。
③os ... ①上で使用しました。opencvほどの特別感はありませんが重要です。
④カメラ ... 一部のウェブカムなど、プログラムがうまく機能しててもダメな場合があります。そういった場合は、カメラが元から組み込んであるラップトップなどを使用してみると動作すると思います(経験者談)。
プログラム
具体的にはこんな感じです。
import cv2
import os
import sys
# 必要なのは1.カメラ番号、2.新規フォルダ名、3.タグ名
def save_video_iaf(device_num, dir_path, basename):
n = 0
camera = cv2.VideoCapture(device_num)
os.makedirs(dir_path, exist_ok=True)
base_path = os.path.join(dir_path, basename)
while True:
# 動画ファイル保存用の設定
fps = int(camera.get(cv2.CAP_PROP_FPS))
width = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
video = cv2.VideoWriter('{}_{}.avi'.format(base_path, n), fourcc, fps, (width, height))
# 撮影
while True:
_, frame = camera.read()
cv2.imshow('in a flash', frame)
video.write(frame)
#キー操作でwhileループを抜けて終了
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 撮影を続けるか確認
inv = input('まだやるかい:y/n >>>')
if inv == 'y':
n+=1
elif inv == 'n':
camera.release()
cv2.destroyAllWindows()
break
プログラムの説明
-
save_video_iafという名前の関数を定義しました。この関数の引数は①device_num(カメラの番号)、②dir_path(動画を保存するディレクトリ名)、③basename(撮り回した動画の名前の一部)となっています。ここでcv2のVideoCaptureを使い、動画を撮れるようにします。次に、osのmakedirsでdir_pathの名前のディレクトリを作成します。そして、base_pathに保存先パスとbasenameを足したものを格納します。この操作のおかげで「C:/~/フォルダ名/basename.avi」というように動画を保存できるようになります。
-
第一のwhile文が始まります。ここで、動画のfps、幅、高さを整数値で取得し、動画のコーデックの種類(ここでは*MPEGを使用)を決めます。また、cv2のVideoWriterを使い、動画ファイルを保存するときの取り決めを書いておきます。この場合、「dir_pathのフォルダ内に、basename_n.aviという名前で動画を保存していく」という取り決めが出来ています。
-
第二のwhile文が始まります。従来はret, frameにVideoCaptureクラスのreadメソッドを用いた返り値が入りますが、retは動作確認の時にしか使わないので、アンダースコアを記述しています(効果がどの程度あるかは知りません)。次に、cv2.imshowで撮影ウィンドウが表示されます。そして、VideoWriterクラスのwriteメソッドによって動画を保存します。PCのキーでqを入力すれば動画の撮影が止まります(ウィンドウは最後まで消えず、また撮影の合間も表示され続けます)。
第二のwhile文はここで一旦終わります。 -
次の撮影を始めるか確認します。これには標準のinput関数を使用します。pythonにyを入力すれば次の動画を撮影、nを入力すればそこで撮影が終了します。
結果
# 試用
save_video_iaf(0, 'movies', 'ex')
コーディング中に花〇薫の台詞「まだやるかい」が出てきてしまったので一枚目のような文になりました。あるあるですね。
おわりに
当初の目的はおおよそ達成できましたが、使いづらさが今後の課題として残りました。yとnの入力とqの入力をそれぞれする際に、マウスを動かしてウィンドウを行き来する必要があり、これはかなり手間なように感じられます。そのため、今後はそういった操作を省けるようなプログラムを書いて、もっと効率的かつ使いやすくしたいと思いました。
ちなみに、私はバレーボールに興味があるので、コートのエンドライン側から俯瞰して練習/試合を撮影し、データを集めるのに使おうと考えています。研究頑張ろう。うん(自問自答)
今回はここまでです。それでは!
参考記事
https://note.nkmk.me/python-opencv-camera-to-still-image/
https://www.python.jp/train/string/input.html
https://whitewell.sakura.ne.jp/OpenCV/py_tutorials/py_gui/py_video_display/py_video_display.html
https://rikoubou.hatenablog.com/entry/2019/01/15/174751
https://watlab-blog.com/2019/09/26/webcamera-save/