はじめに
Webカメラで動画を取得して画像処理を行う方法について下の投稿で解説しましたが、本記事では、OpenCVのcv2.VideoCapture
クラスを使って動画を読み込み、各フレームに画像処理(動画処理)を施す方法を解説します。
あわせて、cv2.VideoWriter
クラスを使った、画像処理後の動画を保存する方法についても紹介します。
動画ファイルの読み込みと保存
cv2.VideoCaptureで動画を読み込む
OpenCVを使って動画ファイルを読み込むには、cv2.VideoCapture
クラスを使用します。cv2.VideoCapture
クラスはカメラによるキャプチャもできますが、動画ファイルの読み込みにも対応しています。
動画ファイルの読み込みの際は下のコンストラクタでインスタンスを生成します。
引数
名称 | 説明 |
入力動画ファイル名(必須) | 動画ファイル名、画像シーケンス、ビデオストリームの URL、GStreamerのビデオ ストリーム、または IP カメラ フィードには独自の URL スキーム。 |
apiPreference(オプション) | 動画ファイルを読み込むために使用するAPIの優先順位を指定するために使用します。(デフォルト:cv2.CAP_ANY ) |
apiPreference
はプラットフォームに依存し、環境によって異なります。
一般的には、デフォルトの設定で問題なく動作することが多いです。
設定可能な値を下の表にまとめました。
apiPreference | 説明 |
cv2.CAP_ANY | 利用可能なすべてのAPIを試し、最初に動作するものが使用されます。 この設定は、特定のAPIを指定せずに動画ファイルを読み込む場合に使用されます。(デフォルト値) |
cv2.CAP_VFW | Video for Windows(VFW)APIを使用するように指定します。 VFWはWindowsプラットフォーム向けのAPIで、古いフォーマットの動画ファイルに対して有用です。 |
cv2.CAP_FFMPEG | FFmpeg(Fast Forward MPEG)APIを使用するように指定します。 FFmpegはオープンソースのマルチメディアフレームワークで、多くのフォーマットとコーデックをサポートしています。これは多くの場合、高度な動画処理のために使用されます。 |
cv2.VideoCapture
クラスは、多くの動画フォーマットの読み込みをサポートしています。ただし、サポートされるフォーマットはOpenCVのビルドオプションに依存し、インストールされたOpenCVバージョンによって異なる場合があります。以下は一般的なサポートされるフォーマットのいくつかですが、すべてのフォーマットを網羅することは難しいと思われます。
動画フォーマット名 | 説明 |
AVI(Audio Video Interleave) | AVIはWindowsで広く使用されている動画フォーマットで、OpenCVでもサポートされています。 |
MP4(MPEG-4) | MP4は高圧縮率の動画フォーマットであり、一般的に使用されています。 多くのOpenCVビルドでサポートされています。 |
MKV(Matroska Video) | MKVはオープンなコンテナフォーマットで、高品質なビデオとオーディオストリームをサポートしています。 一部のビルドでサポートされています。 |
MOV(QuickTime Movie) | MOVはApple QuickTimeで使用されるフォーマットで、一般的なマルチメディアコンテナです。 多くのOpenCVビルドでサポートされています。 |
FLV(Flash Video) | FLVはAdobe Flashプレーヤーで使用されるフォーマットで、ストリーミングビデオに適しています。 多くのビルドでサポートされています。 |
WebM | WebMはオープンなウェブ用ビデオフォーマットで、オープンソースのコーデックを使用しています。 一部のビルドでサポートされています。 |
WMV(Windows Media Video) | WMVはMicrosoftのWindows Media Playerで使用されるフォーマットです。 一部のビルドでサポートされています。 |
cv2.VideoCapture
が読み込める動画フォーマットの例戻り値
cv2.VideoCapture
クラスのインスタンス。
cv2.VideoWriterで動画を保存する
OpenCVのcv2.VideoWriter
クラスで動画ファイルを保存します。
下のコンストラクタでインスタンスを生成します。
引数
名称 | 説明 |
出力動画ファイル名(必須) | 出力する動画ファイル名 |
fourcc(必須) | コーデック |
fps(必須) | 作成されたビデオ ストリームのフレームレート |
frameSize(必須) | フレームのサイズを(フレーム幅, フレーム高さ)の形式のタプルで指定します。 |
isColor(オプション) | カラー画像の時、True を指定し、グレースケール画像の時Falseを指定する。(デフォルト:True ) |
下の表は引数のfourccで指定できるコーデックの例です。
”fourcc”とはビデオコーデックなどを4文字で表す識別子のことです。
この一覧に示したもの一般的なコーデックのfourccコードですが、OpenCVが特定のfourccコードをサポートしているかどうかは、OpenCVのバージョンやビルドオプションに依存します。
筆者が調べた限りでは、自分のOpenCV環境で使用可能なコーデックの一覧を取得する方法は見つかりませんでした。
自分のOpenCV環境でどのコーデックが利用できるかは、プログラムを動かして確認するしか無い様です。
コーデック一覧を取得する方法をご存知の方がおりましたら、コメントで共有していただけたら嬉しいです。
コーデック | fourccコード | 保存ファイルの拡張子 |
MP4V | *'mp4v' | .mp4 |
DIVX | *'DIVX' | .avi |
XVID | *'xvid' | .avi |
WMV1 | *'WMV1' | .wmv |
WMV2 | *'WMV2' | .wmv |
MJPG | *'MJPG' | .avi |
H263 | *'H263' | .avi |
X264 | *'X264' | .mp4 |
YUY2 | *'YUY2' | .avi |
I420 | *'I420' | .avi |
PIM1 | *'PIM1' | .avi |
NV12 | *'NV12' | .avi |
RGBA | *'RGBA' | .avi |
使い方
動画ファイルを読み込みんで、画像処理後、動画ファイルを保存するまでの基本的な使い方は次の様な手順となります。
cv2.VideoCapture
クラスのを作成し、動画を読み込む:
cv2.VideoCapture
クラスののコンストラクタの引数として読み込む動画ファイル名を指定します。
# 動画ファイルを開く cap = cv2.VideoCapture('movie.mp4')
- 動画のプロパティーを取得:
読み込んだ動画ファイルのプロパティーを取得します。
取得する項目は、動画の幅および高さ、FPSです。
# 各種プロパティーを取得 frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # フレームの幅 frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # フレームの高さ fps = float(cap.get(cv2.CAP_PROP_FPS)) # FPS
- 動画のコーデックを指定して
cv2.VideoWriter
クラスののインスタンスを作成:
cv2.VideoWriter_fourcc関数で動画のコーデックを指定して、その戻り値をcv2.VideoWriterクラスのコンストラクタの引数に指定します。
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 動画のコーデックを指定 out = cv2.VideoWriter(output_file, fourcc, fps, (frame_width, frame_height), False)
- フレームの読み取り:
cv2.VideoCapture
クラスのcap.read()
メソッドを使用して、動画から1フレームを読み取ります。
戻り値のret
はフレームの読み取りが成功したかどうかを示すブール値、frame
は読み取られたフレームの画像データです。
# フレームを1つ読み込む ret, frame = cap.read()
- フレームごとに画像処理を施す:
必要に応じで画像処理を実行します。
コーデックの種類によって画像がカラーまたはグレースケール、フレームのサイズに影響があります。
下のコードではカラー画像をグレースケールに変換しています。
3にてcv2.VideoWriter
クラスののインスタンス作成時の引数isColor
にFalseを設定したのは、このためです。
# 画像処理を施す(例:グレースケール変換) gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
- フレームごとに追記しながら、動画ファイルを保存:
# 動画にフレームを書き込む out.write(gray_frame)
- 終了処理:
リソースの解放を行います。
# リソースを解放して終了 cap.release() out.release()
サンプルコード全体は下の様になります。
import cv2 # 動画ファイルを開く cap = cv2.VideoCapture("movie.mp4") if not cap.isOpened(): print("動画ファイルを開けませんでした。") exit() # 各種プロパティーを取得 frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # フレームの幅 frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # フレームの高さ fps = float(cap.get(cv2.CAP_PROP_FPS)) # FPS # VideoWriter を作成する。 output_file = "output_video.avi" # 保存する動画ファイル名 fourcc = cv2.VideoWriter_fourcc(*'xvid') # 動画のコーデックを指定 # カラー画像をグレースケールに変換して動画として保存するためisColor=Falseとしています。 out = cv2.VideoWriter(output_file, fourcc, fps, (frame_width, frame_height), False) while cap.isOpened(): # フレームを1つ読み込む ret, frame = cap.read() # 動画の最後に到達したら終了 if not ret: break # 画像処理を施す(例:グレースケール変換) gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 動画にフレームを書き込む out.write(gray_frame) # リソースを解放して終了 cap.release() out.release()
おわりに
OpenCVで動画の編集と保存を行う方法について解説しました。
筆者の環境では約30秒ほどの動画の処理にグレースケールとして保存した場合、約4秒かかりました。
画像処理せずにカラー画像のまま動画として保存した場合は40秒前後の処理時間となりました。カラー動画の処理には時間がかかる様です。
fourccコードなどわかりにくい部分もありますが、静止画だけでなく動画の処理ができることで幅広いアプリケーションに応用できる様になりますね。
ご質問や取り上げて欲しい内容などがありましたら、いつでもお気軽にコメントをお願いします。
最後までご覧いただきありがとうございました。
参考リンク
cv::VideoCapture Class Reference
Class for video capturing from video files, image sequences or cameras.
cv::VideoWriter Class Reference
OpenCV: cv::VideoWriter Class Reference
Video Codecs by FOURCC
These are the FOURCCs I know about that refer to compressed formats (the ones that you see displayed when you don't have the right codec installed to play a given AVI file).
FFmpeg
FFmpeg. A complete, cross-platform solution to record, convert and stream audio and video.
■(広告)OpenCVの参考書としてどうぞ!■
(広告)あなたに合ったプログラミング スクールが見つかるかも
プログラミングの学習が、新しい世界を開きます。副業からキャリアの転換まで、目標に向かって一歩を踏み出しましょう。
これらのプログラミング スクールは、あなたの目的に合わせて選択できるさまざまなプログラムを提供しています。どのスクールを選ぶにせよ、プログラミングは未来への扉を開き、新しい機会を切り開く手段として素晴らしい選択です。あなたの夢や目標を実現する第一歩を踏み出す準備はできていますか?