【Python・OpenCV】動画ファイルの画像処理と動画を保存する方法

※当サイトではアフィリエイト広告を利用しています

Python プログラミング 画像処理

【Python・OpenCV】動画ファイルの画像処理と動画を保存する方法

はじめに

Webカメラで動画を取得して画像処理を行う方法について下の投稿で解説しましたが、本記事では、OpenCVのcv2.VideoCaptureクラスを使って動画を読み込み、各フレームに画像処理(動画処理)を施す方法を解説します。
あわせて、cv2.VideoWriterクラスを使った、画像処理後の動画を保存する方法についても紹介します。

動画ファイルの読み込みと保存

cv2.VideoCaptureで動画を読み込む

OpenCVを使って動画ファイルを読み込むには、cv2.VideoCaptureクラスを使用します。cv2.VideoCaptureクラスはカメラによるキャプチャもできますが、動画ファイルの読み込みにも対応しています。

動画ファイルの読み込みの際は下のコンストラクタでインスタンスを生成します。

cv2.VideoCapture(入力動画ファイル名[, apiPreference])

引数

名称説明
入力動画ファイル名(必須)動画ファイル名、画像シーケンス、ビデオストリームの URL、GStreamerのビデオ ストリーム、または IP カメラ フィードには独自の URL スキーム。
apiPreference(オプション)動画ファイルを読み込むために使用するAPIの優先順位を指定するために使用します。(デフォルト:cv2.CAP_ANY

apiPreferenceはプラットフォームに依存し、環境によって異なります。
一般的には、デフォルトの設定で問題なく動作することが多いです。

ポイント

特定のAPIを使用する理由がない限り、通常はapiPreferenceを指定する必要はありませんが、動画ファイルを扱う上で問題が発生した場合、異なるapiPreferenceを試すことが解決策の一つとなるかもしれません。

設定可能な値を下の表にまとめました。

apiPreference説明
cv2.CAP_ANY利用可能なすべてのAPIを試し、最初に動作するものが使用されます。
この設定は、特定のAPIを指定せずに動画ファイルを読み込む場合に使用されます。(デフォルト値)
cv2.CAP_VFWVideo for Windows(VFW)APIを使用するように指定します。
VFWはWindowsプラットフォーム向けのAPIで、古いフォーマットの動画ファイルに対して有用です。
cv2.CAP_FFMPEGFFmpeg(Fast Forward MPEG)APIを使用するように指定します。
FFmpegはオープンソースのマルチメディアフレームワークで、多くのフォーマットとコーデックをサポートしています。これは多くの場合、高度な動画処理のために使用されます。
apiPreference

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プレーヤーで使用されるフォーマットで、ストリーミングビデオに適しています。
多くのビルドでサポートされています。
WebMWebMはオープンなウェブ用ビデオフォーマットで、オープンソースのコーデックを使用しています。
一部のビルドでサポートされています。
WMV(Windows Media Video)WMVはMicrosoftのWindows Media Playerで使用されるフォーマットです。
一部のビルドでサポートされています。
cv2.VideoCaptureが読み込める動画フォーマットの例

戻り値

cv2.VideoCaptureクラスのインスタンス。

cv2.VideoWriterで動画を保存する

OpenCVのcv2.VideoWriterクラスで動画ファイルを保存します。

下のコンストラクタでインスタンスを生成します。

cv2.VideoWriter(出力動画ファイル名, fourcc, fps, frameSize[, isColor])

引数

名称説明
出力動画ファイル名(必須)出力する動画ファイル名
fourcc(必須)コーデック
fps(必須)作成されたビデオ ストリームのフレームレート
frameSize(必須)フレームのサイズを(フレーム幅, フレーム高さ)の形式のタプルで指定します。
isColor(オプション)カラー画像の時、Trueを指定し、グレースケール画像の時Falseを指定する。(デフォルト:True

ポイント

引数の"isColor"を正しく指定しないと、保存した動画はエラーで再生できません。

下の表は引数の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
fourccコードの例

メモ

H263はサポートするフレームサイズが下記に限定されるので、write関数で書き込む前にフレームのサイズを変更する必要があります。

フレームサイズ:128x96, 176x144, 352x288, 704x576, 1408x1152

使い方

動画ファイルを読み込みんで、画像処理後、動画ファイルを保存するまでの基本的な使い方は次の様な手順となります。

cv2.VideoCaptureクラスで動画ファイルを読み込んで保存する手順

  1. cv2.VideoCaptureクラスのインスタンスを作成し、動画を読み込む
  2. 動画のプロパティーを取得
  3. cv2.VideoWriterクラスののインスタンスを作成
  4. フレームの読み取り
  5. フレームごとに画像処理を行う
  6. フレームごとに追記しながら、動画ファイルを保存
  7. 終了処理
  1. cv2.VideoCaptureクラスのを作成し、動画を読み込む

cv2.VideoCaptureクラスののコンストラクタの引数として読み込む動画ファイル名を指定します。

# 動画ファイルを開く
cap = cv2.VideoCapture('movie.mp4')
  1. 動画のプロパティーを取得

読み込んだ動画ファイルのプロパティーを取得します。
取得する項目は、動画の幅および高さ、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
  1. 動画のコーデックを指定してcv2.VideoWriterクラスののインスタンスを作成:

cv2.VideoWriter_fourcc関数で動画のコーデックを指定して、その戻り値をcv2.VideoWriterクラスのコンストラクタの引数に指定します。

fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # 動画のコーデックを指定
out = cv2.VideoWriter(output_file, fourcc, fps, (frame_width, frame_height), False)
  1. フレームの読み取り

cv2.VideoCaptureクラスのcap.read()メソッドを使用して、動画から1フレームを読み取ります。
戻り値のretはフレームの読み取りが成功したかどうかを示すブール値、frameは読み取られたフレームの画像データです。

# フレームを1つ読み込む
ret, frame = cap.read()
  1. フレームごとに画像処理を施す

必要に応じで画像処理を実行します。
コーデックの種類によって画像がカラーまたはグレースケール、フレームのサイズに影響があります。
下のコードではカラー画像をグレースケールに変換しています。
にてcv2.VideoWriterクラスののインスタンス作成時の引数isColorにFalseを設定したのは、このためです。

# 画像処理を施す(例:グレースケール変換)
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  1. フレームごとに追記しながら、動画ファイルを保存
# 動画にフレームを書き込む
out.write(gray_frame)
  1. 終了処理

リソースの解放を行います。

# リソースを解放して終了
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コードなどわかりにくい部分もありますが、静止画だけでなく動画の処理ができることで幅広いアプリケーションに応用できる様になりますね。

ご質問や取り上げて欲しい内容などがありましたら、いつでもお気軽にコメントをお願いします。
最後までご覧いただきありがとうございました。

参考リンク

■(広告)OpenCVの参考書としてどうぞ!■

(広告)あなたに合ったプログラミング スクールが見つかるかも

プログラミングの学習が、新しい世界を開きます。副業からキャリアの転換まで、目標に向かって一歩を踏み出しましょう。

これらのプログラミング スクールは、あなたの目的に合わせて選択できるさまざまなプログラムを提供しています。どのスクールを選ぶにせよ、プログラミングは未来への扉を開き、新しい機会を切り開く手段として素晴らしい選択です。あなたの夢や目標を実現する第一歩を踏み出す準備はできていますか?

-Python, プログラミング, 画像処理
-