ビデオ/ストリームからキー フレームを抽出する必要があります。標準的な実装はありますか。オープンCVを使用しています。(現在、毎秒フレームを抽出していますが、これはパフォーマンスを向上させる必要があります。)したがって、最適化された実装がある場合は、ここに返信してください。
5 に答える
ffmpeg を使用すると、次のコードを使用してすべてのキー フレームを抽出できます。
ffmpeg -vf select="eq(pict_type\,PICT_TYPE_I)" -i yourvideo.mp4 -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg
ffmpeg コマンド ラインで -vf に続くのは、Filtergraph の説明です。選択フィルターは、出力に渡すフレームを選択します。フィルタの定数は「pict_type」で、値は「PICT_TYPE_I」です。したがって、ffmpeg はキー フレームのみを出力に渡します。
-vsync 2 は、ffmpeg が各キー フレームに対して複数のコピーを生成するのを防ぎます。
-f image2 は、ビデオ フレームを画像ファイルに書き込みます。出力ファイル名はパターンによって指定され、連続番号の付いた一連のファイルを生成するために使用できます。パターンには、文字列 "%d" または "%0Nd" が含まれる場合があります。
キーフレームは、以前のものとは大きく異なるコンテンツを提示するフレームであると想定します (正式な定義ではありませんが、適合します)。フレームiとi+1を取ります。cv2.absDiffを使用してフレーム間の差を計算し、cv2.sumElemsを使用してすべてのピクセル差の合計を取得します。すべてのフレームiに対してこれを行います。これにより、ビデオ ストリームが1 次元の信号に縮小されます。ピークを探すこの信号で、これらのピークに対応するキーフレームを選択します。ピークを見つけるには、キーと思われるフレームを手動で見つけて、そのエラーをエラーしきい値にするか、統計を使用して自動的にこの信号のしきい値を選択します (たとえば、エラーが 1 stdev よりも大きい任意のフレーム i+1平均誤差)。
上記のコードに問題がある場合は、代わりにこの引数の順序を試してください。
ffmpeg -i yourVideo.mp4 -vf select='eq(pict_type\,I)' -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg
ffmpeg ソリューションはうまく機能するはずです。
選択フィルター 'eq(pict_type\,PICT_TYPE_I)' で問題に直面している場合は、フィルターを 'eq(pict_type\,I)' として試してください。これはしばらく壊れていたため、ffmpeg の一部のバージョンでは定数が認識されない可能性があります。修正はここで見ることができます。
最終的に私のために働いた最後のコマンドは次のとおりです。
ffmpeg -vf select='eq(pict_type\,I)' -i yourVideo.mp4 -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg
ffprobe を使用してキー フレームを抽出できます。ffmpeg のツールです。
次のコマンドを使用します。
ffprobe in.mp4 -select_streams v -show_entries frame=key_frame,pkt_pts_time -of csv=nk=1:p=0 | findstr "1,"