動画を保存する際のビデオコーデックの選択方法
概要
ビデオコーデックは、ビデオデータを効率的にエンコード(圧縮符号化)およびデコード(復号化)するためのソフトウェア(アルゴリズム)です。 カメラの映像録画で必要となるコーデックは、ビデオの品質、圧縮率、互換性を考慮する必要があります。この記事では、H.264、XVID、MJPGなどの一般的なビデオコーデックの特性について詳しく解説します。また、PythonとOpenCVを使用して、これらのコーデックを用いてビデオを保存する方法も紹介してます。
出力結果
プログラム全体
#解説1
import cv2
#解説2
# UVCカメラを開く
cap = cv2.VideoCapture(0)
#解説3
# フレームレートを取得
fps = cap.get(cv2.CAP_PROP_FPS)
#解説4
# ビデオライターを作成(AVIコンテナとXVIDコーデックを使用)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, fps, (640, 480))
# ビデオライターを作成(mp4コンテナとMJPGを使用)
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output.avi', fourcc, fps, (640, 480))
# ビデオライターを作成(webmコンテナとVP9 を使用)
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('output.mov', fourcc, fps, (640, 480))
# ビデオライターを作成(mp4コンテナとH.264コーデックを使用)
fourcc = cv2.VideoWriter_fourcc(*'H264')
out = cv2.VideoWriter('output.mp4', fourcc, fps, (640, 480))
#解説5
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
#解説6
# カメラとビデオライターを解放
cap.release()
out.release()
cv2.destroyAllWindows()
解説
解説1: OpenCVのインポート
import cv2
OpenCVは、画像処理やコンピュータビジョンのためのオープンソースライブラリです。これを使うことで、画像の読み込み、変換、保存等、画像処理に関連する多くの機能を利用することができます。
解説2: カメラの開始
cap = cv2.VideoCapture(0)
ここでは、UVCカメラを開いて、その映像を取得するためのオブジェクトを作成しています。cv2.VideoCapture(0)
という関数は、引数にUVCカメラのIDを取り、そのカメラにアクセスするためのVideoCapture
オブジェクトを返しています。ここでの0
は、通常はシステムに接続されているデフォルトのカメラ(通常は内蔵カメラ)を指しますが、使用しているカメラによって割り振られる番号が異なりますのでご注意ください。
補足:OpenCVにおけるデバイスID
デバイスが複数接続された場合、このIDは、いつも同じとは限りません。デバイスの起動やシステムへの接続順によって変わることがほとんどです。 TheImagingSource社が提供しているSDK(ICImagingControl)ではカメラ本体にシリアル番号が割り振られており、カメラ毎に設定が容易にできます。詳細は下記をご覧ください。 https://www.argocorp.com/software/sdk/ICImagingControl/Sample_program/Python_34/open-with-built-in-dialog.html
解説3: フレームレートの取得
fps = cap.get(cv2.CAP_PROP_FPS)
カメラのフレームレート(1秒あたりのフレーム数)を取得しています。fpsの変数として格納したフレームレートは、ビデオを保存する際のフレームレートとして使用します。
解説4: ビデオライターの作成
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, fps, (640, 480))
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output.avi', fourcc, fps, (640, 480))
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('output.mov', fourcc, fps, (640, 480))
fourcc = cv2.VideoWriter_fourcc(*'H264')
out = cv2.VideoWriter('output.mp4', fourcc, fps, (640, 480))
ビデオを保存するために、ビデオライターオブジェクトを作成しています。 cv2.VideoWriter_fourccの中の引数はビデオコーデックや圧縮フォーマットなどを4文字で表した識別子を指しています。利用可能なコーデックはOpenCVを動かしているPCにインストールされているコーデック次第です。ここでは、下記の異なるコーデック('XVID'、'MJPG'、'MP4V'、'H264')とコンテナ('.avi'、'.mov'、'.mp4')を使用して、ビデオを保存します。使用しないコーデックはコメントアウトしてください。
コーデック | 拡張子 |
---|---|
XVID | .avi |
MJPG | .avi |
MP4V | .mov |
H264 | .mp4 |
例として4種類記載していますが、'XVID'、'MJPG'、'MP4V'、'H264'のいずれか1種類を選択してください。ただし、PCにインストールされているコーデックに依存するので、記載すれば必ず動作することはありません。
補足:FOURCC
FOURCCのリストは以下参照してください。
https://fourcc.org/codecs/
HEVCのコーデックがインストールされていない環境でfourcc = cv2.VideoWriter_fourcc(*'H264')
と指定すると下記のようにエラーとして下記のように表示されますので注意してください。
OpenCV: FFMPEG: tag 0x43564548/'HEVC' is not found (format 'mp4 / MP4 (MPEG-4 Part 14)')'
カメラから送られてくるデータの圧縮をするのにCPUの処理負荷がかかりますが、PCに搭載されているGPUを利用してエンコード(ハードウェアエンコード)を行うことが可能です。 このハードウェアエンコードを行うことでCPUへの負荷が軽く抑えられます。詳細は下記のサンプルをご覧ください。
https://www.argocorp.com/software/sdk/ICImagingControl/Sample_program/Python_34/pythonnet-qt5-mediastreamsink.html
解説5: フレームの読み込みと保存
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
カメラが正常に開いている間に、while文のループ処理をしています。ループ処理の中で、cap.read()
を使ってカメラからフレームを取得します。その際に正常に画像を取得できていれば、out.write(frame)
を使ってcv2.VideoWriterオブジェクトを使って、output.mp4のビデオファイルに書き込む処理を行っています。また、cv2.imshow('frame',frame)
は取得したフレームを画面に表示します。'q'キーが押されたらループを抜けます。
解説6: リソースの解放
cap.release()
out.release()
cv2.destroyAllWindows()
プログラムの最後でカメラとビデオライターのリソースを解放しています。プログラムが終了した際に、リソースのリークを防ぐために必要となります。cap.release()
とout.release()
はカメラと解説4で指定したビデオライターのリソースを解放し、最後にcv2.destroyAllWindows()
はOpenCVが作成したすべてのウィンドウを閉じます。