この記事は公開されてから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カードに対して、パスを手入力することなく自動で探索して、動画を書き込む処理を実装しました。