Android 5.2で作成したアプリケーションを使用して、タブレットのフロントカムから複数のビデオを記録しました。各ビデオの開始タイムスタンプをミリ秒(Unix時間)で保存しました。
残念ながら、各ビデオのフレームレートは異なります(20〜30の範囲)。 OpenCVを使用すると、各ビデオのフレームレートを取得できます。
import cv2
video = cv2.VideoCapture(videoFile)
fps = video.get(cv2.CAP_PROP_FPS)
これはうまく機能し、理論的には、ビデオの各フレームに1000/fps(ミリ秒)を追加することができます。ただし、これは録画全体を通してフレームレートが安定していることを前提としています。これが事実かどうかはわかりません。
Pythonに、フレームレートに関係なくビデオの各フレームのタイムスタンプ(ミリ秒単位)を取得する可能性はありますか?
cv2.CAP_PROP_POS_MSEC
が必要です。さまざまなキャプチャプロパティをすべて表示します here 。
編集:実際、 DanMašek が指摘したように、そのプロパティを取得すると、OpenCVは 正確にその計算を行う のように見えます(少なくともFFMPEGを使用していると仮定します) ):
case CV_FFMPEG_CAP_PROP_POS_MSEC:
return 1000.0*(double)frame_number/get_fps();
したがって、常に一定のフレームレートの仮定に依存するようです。ただし、一定のフレームレートを想定しても、1000/fps
を追加し続けるだけでなく、フレーム番号を掛けることが重要です。フロートを繰り返し追加するとエラーが発生し、長いビデオで大きな違いが生じる可能性があります。例えば:
import cv2
cap = cv2.VideoCapture('vancouver2.mp4')
fps = cap.get(cv2.CAP_PROP_FPS)
timestamps = [cap.get(cv2.CAP_PROP_POS_MSEC)]
calc_timestamps = [0.0]
while(cap.isOpened()):
frame_exists, curr_frame = cap.read()
if frame_exists:
timestamps.append(cap.get(cv2.CAP_PROP_POS_MSEC))
calc_timestamps.append(calc_timestamps[-1] + 1000/fps)
else:
break
cap.release()
for i, (ts, cts) in enumerate(Zip(timestamps, calc_timestamps)):
print('Frame %d difference:'%i, abs(ts - cts))
フレーム0の差:0.0
フレーム1の差:0.0
フレーム2の差:0.0
フレーム3の違い:1.4210854715202004e-14
フレーム4の違い:0.011111111111091532
フレーム5の違い:0.011111111111091532
フレーム6の違い:0.011111111111091532
フレーム7の違い:0.011111111111119953
フレーム8の違い:0.022222222222183063
フレーム9の違い:0.022222222222183063
...
フレーム294の違い:0.8111111111411446
これはもちろんミリ秒単位であるため、それほど大きくはないようです。しかし、ここでは計算で1msほど遅れています。これは、11秒のビデオのためだけです。とにかく、このプロパティを使用する方が簡単です。