タイトル通り、動画データを画像データに変換してみようと思います。これができるようになると、画像解析ができる人は動画の解析もできるようになるんです。動画から画像に変換するためにOpenCVというライブラリを用いますが、簡単なのでOpenCVの入門としては最適かもしれません。
この記事では、PythonのOpenCVライブラリを用いて動画を画像に変換する具体的な方法をご紹介します。
変換可能な動画と画像の種類
変換可能な動画と画像データの種類は何かなと思って、OpenCVの公式ドキュメントを見てみましたが載ってなかったので自分で試してみて使えるものを洗い出しました。
動画に関しては、「.mov」「.mp4」が使用可能で
画像に関しては、「.jpg」「.png」「.tiff」に変換可能でした。
ですから、ここで使っている「変換」という言葉の意味は、正確には「動画データからフレームを切り出して、そのフレームを画像データとして保存する」という意味です。
動画から画像に変換する具体的な手順(サンプルコードあり)
OpenCVをインストールする
pipコマンドを用いれば簡単にOpenCVのライブラリがインストールできます。
次のようにターミナルにコマンドを入力して、returnキーを押してください。
pip install opencv-python
最終的にSuccessfullyというワードが書かれていれば、無事にインストール完了です。
すでにインストールされている場合は、already satisfiedというワードが表示されると思います。
動画を用意する
今回は以下の.mp4の拡張子の動画からjpg形式の画像に変換しようと思います。
FireFry.mp4という名前でDesktop/Dr.code/python/data-analysis/convert-movie-to-image
に置きます。
プログラムを実行する
import cv2
movie_name = 'FireFly'
movie = movie_name + '.mp4'
cap = cv2.VideoCapture(movie)
# 幅
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
print('width : {:.0f} px'.format(width))
# 高さ
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print('height : {:.0f} px'.format(height))
# 総フレーム数
num_frame = cap.get(cv2.CAP_PROP_FRAME_COUNT)
print('number of frames : {:.0f}'.format(num_frame))
# fps
fps = cap.get(cv2.CAP_PROP_FPS)
print('fps : {:f}'.format(fps))
count = 0
while True:
ret, frame = cap.read()
if ret == True:
count += 1
# 画像を生成
cv2.imwrite('{:s}_{:06d}.jpg'.format(movie_name, count), frame)
else:
break
コードが書けたらこのファイルをconvert.py
という名前でDesktop/Dr.code/python/data-analysis/convert-movie-to-image
に保存しましょう。
ターミナル上でcwdをDesktop/Dr.code/python/data-analysis/convert-movie-to-image
に変更し、python convert.py
とコマンド入力し、プログラムを実行しましょう。
プログラムが正常に動作すると、1290枚のjpgファイルが生成されると思います!
コードの解説
このプログラムで重要なのは、5行目の
cap = cv2.VideoCapture(movie)
と26行目の
cv2.imwrite('{:s}_{:06d}.tif'.format(movie_name, count), frame)
の部分です。
前者が動画ファイルの情報をOpenCVのVideoCapture()
を使って読み込んでおり、
後者が動画のあるフレームをimwrite()
を使って画像として書き込んでいます。フレームに番号を振っておくとあとで解析がしやすいので、画像の名前にフレーム番号を書き込んでいます。
# 幅
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
print('width : {:.0f} px'.format(width))
# 高さ
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print('height : {:.0f} px'.format(height))
# 総フレーム数
num_frame = cap.get(cv2.CAP_PROP_FRAME_COUNT)
print('number of frames : {:.0f}'.format(num_frame))
# fps
fps = cap.get(cv2.CAP_PROP_FPS)
print('fps : {:f}'.format(fps))
7~18行目は、動画から画像に変換するにはあまり意味をなさないコードです。
これは、cap.get()
メソッドを使って、動画のフレームに関する情報を取得しています。フレームの横幅と高さのピクセル数、フレームの総数、1秒あたり何フレームか(fps)を取得しています。cap
という変数にはcv2.VideoCapture(movie)
で動画の情報が格納されているから、cap.get()
で情報が取得できるということに注意してください。
ret, frame = cap.read()
ループを繰り返すとret
とframe
が更新されていきます。
フレームがあるときはret
はTrue
ですが、フレームがなくなるとFlase
になります。Flase
になるとループ終了です。