プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2021/08/03

[python] ネットワークカメラの画像を RTSP で取得して表示・保存

update2021/08/13 event_note2021/08/03 7:04

やり方はいろいろあると思いますが、OpenCV を使えば簡単にできました。

画像を取得して表示

VideoCapture の引数に RTSP の URL を記述するだけで簡単に画像を取得できます。
URL はネットワークカメラの仕様を確認してください。
今回は Panasonic のカメラを使いました。

import cv2

user_id = "admin" 
user_pw = "password" 
host = "192.168.0.1" 
cap = cv2.VideoCapture(f"rtsp://{user_id}:{user_pw}@{host}/MediaInput/h264")

while(True):
    try:
        ret, frame = cap.read()
        if ret == True:
            cv2.imshow('VIDEO', frame)
        cv2.waitKey(1)
    except KeyboardInterrupt:
        print("KeyboardInterrupt")
        break

cap.release()
cv2.destroyAllWindows()

VideoCapture の引数を変更すれば、USB カメラや動画ファイルの読み込み、連番のJPGファイルも一括で読み込めたりするので便利です。

保存

今回 RTSP では H.264 で取得しましたが、フレームの処理は OpenCV 側で上手く処理してくれているので、キーフレームとか GOP とか何も考えずに保存できます。

JPG の保存

cv2.imwrite("sample.jpg", frame)

動画の保存

VideoWriter_fourcc でコーデックを指定します。
以下が参考になりました。

画像サイズはキャプチャから取得できる値をそのまま保存時にも使っていますが、フレームレートは取得できないので、直接指定しています。
これが合っていないと当然おかしなことになります(早送り再生やスロー再生したような状態になります)。

import cv2

user_id = "admin" 
user_pw = "password" 
host = "192.168.0.1" 
cap = cv2.VideoCapture(f"rtsp://{user_id}:{user_pw}@{host}/MediaInput/h264")

width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)

fmt = cv2.VideoWriter_fourcc(*'MP4V')
frame_rate = 30.0
writer = cv2.VideoWriter("sample.mp4", fmt, frame_rate, (int(width), int(height)))

while(True):
    try:
        ret, frame = cap.read()
        if ret == True:
            writer.write(frame)
            cv2.imshow('VIDEO', frame)
        cv2.waitKey(1)
    except KeyboardInterrupt:
        print("KeyboardInterrupt")
        break

writer.release()
cap.release()
cv2.destroyAllWindows()