【Ubuntu】SDカードを検索してカメラ映像を録画する方法

2020.11.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

カフェチームの山本です。

現在、カメラで撮影した映像から、商品を取ったユーザを識別しています。開発中、テストなどで入力となる撮影動画を記録することがありますが、動画は容量が大きくなるため、ブート用のドライブのでは空き容量が小さい場合があり、別途SDカードを接続してそこにデータを保存する必要があります。

今回は、SDカードに動画を保存するために、パス・空き容量の調べ方をまとめます。特に複数台のエッジ端末で録画を行う際に、各端末ごとにSDカードを指した際にマウントされるパスを調べるのは手間になるため、容量が大きいディレクトリを検索して選択するようにします。

使用した機器

今回は以下の機器を使用しました。

  • SDカード

https://www.yodobashi.com/product/100000001003146962/

  • SDカードライター

https://www.yodobashi.com/product/100000001005114074/

実装したコード

SDカード検索

/media以下で、容量が大きいディレクトリを検索します。ある程度長時間録画する可能性があったため、検索時に空き容量を確認し、一定(SEARCH_SD_SPACE_GB)以上の空き容量がなければ、例外を発生させるようにしています。

import time
import os

capture_width = 848
capture_height = 480

# free space of sd card
SEARCH_SD_SPACE_GB = 2

# search SD card dir
for media_dir in os.listdir("/media"):
    stat = os.statvfs("/media/" + media_dir)
    free_cap = stat.f_bfree * stat.f_bsize
        gb = free_cap / (1024 * 1024 * 1024)  # B => GB
    print(media_dir, gb)
    if gb > SEARCH_SD_SPACE_GB:
        sd_card_dir = "/media/" + media_dir
        print("SD card dir:", sd_card_dir)
        break
else:
    raise Exception("ERROR: Not found SD card that has free space more than 10GB")

準備

OpenCVのVideoWriterオブジェクトを作成します。今回は、先程検索したSDカードのディレクトリ内に、コードが実行される際の時刻のミリ秒を名前とするフォルダを作成し、動画ファイルを出力するようにしました。

# create video writer object
timestamp_now_millisec = int(time.time() * 1000)
target_dir = sd_card_dir + "/data/" + str(timestamp_now_millisec) + "/"
os.makedirs(target_dir, exist_ok=True)

fourcc = cv2.VideoWriter_fourcc(*'XVID')
target_filename = target_dir + "/" + "rgb_capture.avi"
writer = cv2.VideoWriter(target_filename, fourcc, 10.0, (capture_width, capture_height))

録画・書き込み

OpenCVのVideoCaptureオブジェクトを利用して、カメラから映像をキャプチャします。途中で画像処理したり、認識結果などを描画することもできます。

# create camera capture
cap_cam = cv2.VideoCapture(0)

while True:
    ret, frame = cap_cam.read()
    if not ret:
        break

    # process frame (e.g. detect face and draw result)

    writer.write(frame)
    key = cv2.waitKey(0)
    if key == 27:  # ESC
        break

まとめ

マウントしたSDカードに対して、パスを手入力することなく自動で探索して、動画を書き込む処理を実装しました。