【Python/OpenCV】cv2.VideoCaptureで動画ファイル・Webカメラ映像の読み込みと再生

Python版OpenCVで動画ファイル・カメラの読み込んで画面に再生・表示させる方法をソースコード付きで解説します。

動画ファイルの読み込みと再生(cv2.VideoCapture)

本ページの内容は以下動画で解説しています。

Python版OpenCVでは、cv2.VideoCapture()で動画ファイルを読み込むことができます。
FLVやMP4、AVIなどに対応しています。

以下は、動画ファイル(MP4)を読み込んで画面に表示させるプログラムのソースコードです。


パラメータ 説明
filepath 動画ファイルのパス
frame 1コマ分のキャプチャ画像

VideoCaptureクラスは、カメラもしくは動画ファイルから画像データを取得するためのクラスです。
引数には動画ファイルのパスを指定します。
様々なメソッドがありますが、動画を読み込む場合に最低限使用するメソッドは以下の通りです。

メソッド 説明
read() 1コマ分のキャプチャ画像データを読み込みます(後述する、キャプチャデバイスをキャプチャすることもできます)。
isOpened() 正常に動画ファイルを読み込めたかはメソッドで確認できます(問題なければTrueを返す)。
release() 動画ファイルを閉じます(後述する、キャプチャデバイスをキャプチャしている場合はキャプチャデバイスを終了させます)。

動画から連続的に1コマ分のキャプチャ画像を取得するため、while内でcapture.read() を呼び出して繰り返し処理を行います。取得した1コマの画像データは、変数frameに格納されています。
そして、cv2.imshow() メソッドでウィンドウに1コマの画像データを表示します。

また、while内では、ループを止めるために「q」キーがタイプされたら break するための if 文を記述しています。
while を抜けると、処理を終了させるために VideoCapture を終了して、開いたウィンドウも終了させます。

Webカメラの読み込みと表示(cv2.VideoCapture)

コンピュータに接続されているカメラ(ノートPCに搭載されているフロントカメラやUSBカメラなど)にアクセスして映像を取得することもできます。
その場合は、cv2.VideoCapture()の引数には番号を指定します。
コンピュータにカメラが1台だけしか接続されていない場合には「0」を指定し、複数のカメラが接続されている場合は「1」などの番号を指定します。
環境によっては、1台のカメラしか接続されていなくても番号が「1」だったりするので、うまくいかない場合は数値を1ずつあげて試してみてください。

以下は、Webカメラ映像を取得して画面に表示させるサンプルプログラムのソースコードです。


動画像処理の方法

これまで動画ファイルやWebカメラの映像を画面に表示させてきました。
動画の1フレーム(1コマ)は画像データ(NumPy配列)であり、変数frameに格納されています(色空間はRGB)。
よって、1フレームずつこれまでのように画像処理をかければ動画像処理を行うことができます。

サンプルコード

以下は、1フレーム(frame)ずつcv2.cvtColorメソッドでグレースケール変換させるサンプルプログラムのソースコードです)。


カメラの映像をリアルタイムで処理して表示(再生)する場合も、このようにread()とimshow()の間に任意の処理を加えます。
ただし、1フレームを取得・処理・表示する時間がspf(1/fps)を上回ってしまうと処理落ちします。
例えば、30fpsのカメラ映像でリアルタイム処理する場合、sfp=1/30=0.033なので、1フレームにかける処理時間はおおよそ30ms以内に収める必要があります。

動画のサイズ、FPS、フレーム数などの取得・設定

VideoCaptureクラスのget()メソッドで、読み込んだ動画のプロパティ(サイズ、FPS、フレーム数など)を取得できます。
再生時間(秒数)は総フレーム数 / FPSで計算できます。


VideoCaptureオブジェクトのset()メソッドを使うとプロパティを指定して値を変更できます。
第一引数にプロパティ、第二引数に変更後の値を指定します。
ただし、すべてのプロパティが変更できるわけではありません。


動画ファイルの場合は変更できないためset()メソッドで指定してもFalseが返されます。
カメラの場合はC変更可能でset()メソッドがTrueを返しますが、カメラが対応していないFPSを指定すると値はそのとおりに変更されないため注意が必要です。

また、取得するフレームの現在位置を任意に移動させることもできます。


ただし、総フレーム数以上の値を現在位置に設定するとそれ以上のフレームは存在しないため、read()はFalseとNoneを返します。

関連ページ

【Python版OpenCV入門】画像処理の基礎〜応用例までサンプルコード付きで徹底解説
Python版OpenCVで画像処理プログラミングを行う方法を入門者向けにソースコード付きで解説するページです。

コメント