【Python】OpenCVで動画を読み込み、表示・保存する

前回はOpenCVを用いて画像の読み込み、表示および保存をする方法を紹介しました。今回は、その動画で同様の処理を行っていきます。

画像と比べてやや必要な処理は増えますが、大きな違いはありません。

また、OpenCVでは動画ファイル(.mp4など)だけではなく、WebカメラやUSBカメラから映像を取得し処理することができます。

今回は、それらの映像の取得方法も併せて紹介していきます。

動画を読み込む

Aquarium.mp4

動画ファイルを読み込む

まずは動画ファイル(.mp4)を読み込んでいきます。動画の読み込みにはVideoCapture()を用います。読み込みたい動画ファイルのパスを指定して読み込みます。

import cv2

path = 'input/Aquarium.mp4'
cap = cv2.VideoCapture(path)

USBカメラから動画を取得する

USBカメラを直接つないで動画を取得したい場合は、VideoCapture()の引数を0~の数値を渡します。

import cv2

cap = cv2.VideoCapture(0)

どうやら、繋いだものから順に附番されていくみたいです。0でだめなら1、2を、、といった感じで順に試してみてください。

ネットワークカメラから動画をする

同一ネットワークに存在するネットワークカメラであれば動画を取得することができます。

動画を取得するには、RTSPのURLを指定します。

import cv2

#URLは例です
cap = cv2.VideoCapture("rtsp://user:password@192.168.10.1:47614/ipcam_h264.sdp")

ユーザ名、パスワード、IPアドレスおよびポート番号は、お使いのカメラのものを記載してください。

→カメラ付属の説明書やアプリケーションで確認できると思います。

動画を表示する

動画を取得したら、次は表示していきます。OpenCVでは、動画は画像1コマの連続体として扱います。なので、1フレームずつ処理していくという形になります。

例えば、フレームレートが30/sの動画の場合、動画1秒間の処理はフレーム処理を30回繰り返して行われます。

mp4の動画ファイルを読み込んで表示するサンプルコードを以下に示します。

import cv2

path = r'input/Aquarium.mp4'
cap = cv2.VideoCapture(path)

i=1
while True :
    print("Frame: "+ str(i))
    #フレーム情報取得
    ret, img = cap.read()
    
    #動画が終われば処理終了
    if ret == False:
        break
    

    #動画表示
    cv2.imshow('Video', img)
    i +=1

    
cap.release()
cv2.destroyAllWindows()

While文で条件をTrueにすることで、処理を無限に続けます。While処理中のif文で、動画が終わった時点で処理を終了させます。

連続して処理を続けるというだけで、その中身は画像とほぼ同じです。VideoCapture()からフレーム情報を取得し、imshow()で表示します。

動画の場合、全ての処理終了後にcap.release()で動画を解放します。

動画を出力する

最後に動画を出力するプログラムを作成します。cv2.VideoWriterを使って動画の書き出しを行います。

以下に、読み込んだ動画をグレースケールに変換して出力するサンプルコードを紹介します。

import cv2

path = r'./input/Aquarium.mp4'
cap = cv2.VideoCapture(path)


#動画サイズ取得
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
#フレームレート取得
fps = cap.get(cv2.CAP_PROP_FPS)

#フォーマット指定
fmt = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
#注)グレースケールの画像を出力する場合は第5引数に0を与える
writer = cv2.VideoWriter('./result/output.mp4', fmt, fps, (width, height),0)

i=1
while True :
    print("Frame: "+ str(i))
    #フレーム情報取得
    ret, img = cap.read()
    
    #動画が終われば処理終了
    if ret == False:
        break
    
    #グレースケールに変換
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    #動画表示
    cv2.imshow('Video', img_gray)
    
    #動画書き込み
    writer.write(img_gray)
    
    i +=1
    

cap.release()
#これを忘れるとプログラムが出力ファイルを開きっぱなしになる
writer.release()
cv2.destroyAllWindows()

VideoWriter_fourcc()で動画のフォーマットを指定します。今回はmp4を指定していますが、いろんなフォーマットが指定可能です。

VideoWriter()で出力するファイル情報を保持します。引数には、ファイルのパスやフォーマット、フレームレートやサイズを与えます。インプットとなる動画のフレームレートやサイズは VideoCapture ()のメソッドで取得可能です(詳細はサンプルコードを見てください)。

注意すべきは、グレースケールに変換した動画を出力する場合は、 VideoWriter() の5つ目の引数に0を与えなければならないという点です。オリジナルの画像を出力する場合などではこの引数を渡す必要はありません。

フレームはwhile処理中でwriterに都度書き込みます。

処理の最後は、忘れずに writer.release() します。これをしないと、プログラムが出力ファイルを開いたままになってしまいます。

サンプルコードで出力した動画はこんな感じになります。白黒になってます。

output.mp4

OpenCVの学習におすすめ書籍

PythonでOpenCV始めてみようという方におすすめなのが以下書籍です。実装例も豊富なので、1からコードを書かずとも学習を進めることができます。

オライリーの1冊は読み物というより辞書としての利用におすすめです。お値段結構しますが、細かい情報までしっかりと詰め込まれています。

まとめ

PythonのOpenCVで動画を読み込み~書き出しまでの処理を紹介しました。これで画像解析の第一段階といったところでしょうか。

画像認識では、今回の内容を起点に、画像に様々な処理を加えていきます。画像処理のプログラムにおいて今回のコードの構造は全ての基本となるので、是非内容を理解してもらいたいです。

OpenCVの基礎を身につけるためのロードマップは以下を参考にしてください。

ではでは👋