ソラカメ動画からタイムスタンプを抽出する
2024/05/17
1.はじめに
ソラカメで撮影された動画の撮影開始時刻と終了時刻をミリ秒単位で高速に取得する必要がありました。 このため撮影された動画内のタイムスタンプを画像処理で抽出をし、秒間の平均フレーム数を調査した後、 動画の開始・終了時刻をミリ秒単位の精度で求める試みを行いました。
ソラカメとは
「ソラカメ」は、ソラコム社が提供するWi-Fi 経由でカメラの映像をクラウドに常時録画できるカメラサービスです。
使用動画例
(実際の画像サイズの縮小および右下タイムスタンプ部以外は加工処理を行っています)
■前提条件:
- 解像度:1920×1080
- コーデック:MPEG-4 AAC、H.264
- カラープロファイル HD(1-1-1)
- 画面右下のタイムスタンプの表示位置やフォントは固定
環境
- python: 3.10.13
- OpenCV:4.9.0.80
2.処理内容
OpenCVを用いて、動画をフレーム画像単位で処理していきます。
右下のタイムスタンプ部分の範囲を切り出して処理します。 切り出し画像サイズ(処理対象):70×530 px
年月日と時刻の数値抽出
・最初は2値化後にOCR処理を用いてお手軽に行おうと考えたのですが、 誤認識がある上に、1フレームあたり約0.1秒程かかることがわかりました。
(↓1フレームあたりの処理時間)
・文字認識前の事前処理)時間:約0.00005秒 (2値化等)
・OCRによる文字認識時間:約0.1秒
・認識文字列のチェック時間:約0.00006秒 (yyyy-MM-dd hh:mm:ss フォーマットチェックなど)
高速なリアルタイム処理を検討していることもあり、処理時間がかかりすぎるとのことから 画像テンプレートマッチング手法を用いて行うことにしました。
単純に2値化を行うと白飛びしている部分の数値がうまく検出できなくなります。
数字に縁取り線があることからエッジ抽出画像を用いることにしました。
エッジ抽出に、Cannyフィルタを使用しました。しきい値が低いとノイズを拾いやすいので注意が必要です。
cv2.Canny(image=frame_data, threshold1=600, threshold2=600)
としました。
同じ動画内で取得した0〜9の数字で同様のエッジ抽出処理を行いテンプレート画像を作成しました。
赤枠の領域に対してテンプレート画像を用いて、0〜9を判別します。
検出結果:
数値を検出することができました。
テンプレート画像との一致率を80%を検出OKの条件としました。
様々な動画で約1万フレームほどを処理した結果検出率は100%となり、
100枚の目視確認の結果、すべて正しく検出されていることを確認しました。
処理時間:
1フレームあたり検出処理時間の平均は、0.000437秒となりました。
フレーム数の考慮
動画のヘッダ情報では、FPSは20という数値がとれたのですが、 原因は不明ですが、実際の秒が変わる画像フレーム数をカウントすると、まちまちで安定しておらず、正確に20ではありませんでした。
タイムレコード,フレーム数
2024-02-28 11:25:45,5
2024-02-28 11:25:46,24
2024-02-28 11:25:47,17
2024-02-28 11:25:48,23
2024-02-28 11:25:49,20
2024-02-28 11:25:50,20
2024-02-28 11:25:51,16
2024-02-28 11:25:52,24
2024-02-28 11:25:53,16
2024-02-28 11:25:54,24
そこで1秒間のフレーム数を 動画開始前後の秒数を除いた中間秒のフレーム数で平均を調べることにしました。 中間秒の全フレーム数は傾向として秒間あたり16〜24フレーム数でした。
ただし平均するとFPSはほぼ20前後となりましたので、 (FPS=20)として動画の開始・終了時刻を求めました。
- 開始時刻 = 中間秒の最初のフレーム時刻 ー 開始秒フレーム数(i枚) *FPS
- 終了時刻 = 中間秒の最後のフレーム時刻 + 終了秒フレーム数(k枚) *FPS
3.まとめ
ソラカメ動画から、エッジ画像によるテンプレートマッチングによりタイムスタンプの抽出を行い動画の開始・終了時刻をミリ秒精度で求めました。 タイムスタンプの検出については
- 1フレームあたり検出処理時間の平均は、0.000437秒
- 結果検出率は100%
という結果となりタイムスタンプの検出自体はうまくできたかなと思います。
Tatsuji Kimura