FFmpeg / ImageMagickを使ってMP4から鮮明で明確なサムネイルを取得


6

私の最終的な目標は、30分または1時間の長さの動画から意味のあるスナップショットを取得することです。 "意味のある"は少し野心的なので、私は要件を単純化しました。

ぼやけてはいけません。

当初、これは「キーフレーム」を取得することを意味すると思いました。キーフレームがたくさんあるので、私はビデオの3分に最も近いキーフレームを選ぶことにしました。私はアドバイスに従いました: 3分に最も近いキーフレームを見つけるためのFFmpegコマンド

しかし、問題は、これらのキーフレームがぼやけていることが多いということです。例は次のとおりです。

enter image description here

私はその後試してみました、 FFmpegを使用したビデオ用の意味のあるサムネイル これはより意味のあるスナップショットを取得するのに役立ちましたが、私はまだ(いつもではないが)上記のようなぼやけたフレームを得ることがよくあります。

あなたはこの種のイメージが本質的に2つの異なるシーンの重なりであることに気付くでしょう。時々、しかし、私は私のために働く画像を得ます - このように:

enter image description here

上の画像はあまり意味がありませんが、鮮明です。

理想的には、ぼやけたフレームを返さないようにFFmpegしたいと思います。別の方法として、ぼやけたフレームを検出し、5フレームの中から最もぼやけていないものを選択するためのスクリプトを使用したいと思います。誰もがこれを行う方法を知っていますか?


私は顔検出も使ってみました。私は、識別された顔領域が重なっていると画像がぼやけていると理論づけました。ビデオフレームで顔を検出するのは簡単ではないと思われるので、私はあまり成功しませんでした。ソフトウェアは、ほぼ「完璧な」ポートレート写真を必要とします。
cnfcnf

私はこの論文が関連性があると思いました research.microsoft.com/pubs/68802/… しかしそれはやや複雑に見えます。
cnfcnf

「ぼやけて」というのは、2つの画像が重なっているということですか。それとも、画像が重ならない「ぼやけた」サムネイルの例がありますか。実際のビデオ自体にモーションブラーがあるかもしれないことに注意してください - あなたはそれを取り除くことはできません。最初の画像の人物が実際に動いている場合は、静止フレームごとに少しモーションブラーが発生します。
slhck

あなたが見つけた紙は本当にあなたの問題と関係がない。それはぼけメトリック、すなわち画像が(符号化層において)どの程度ぼやけているかを決定するためのメトリックを記述する。しかし、それを自分で実装しなければならないため、それほど役に立ちません。また、この論文はかなり古く、著者がメトリックの妥当性を証明していることを証明する方法はあまりにも納得のいくものではありません。
slhck

ぼやけて、私の最優先事項は画像を重ねることです。それが最大の問題です。重なり合っていないぼやけた画像があるかどうかについて興味深い質問がありますが、私はまだそれに気付いていません。私は2つの他のリンクを見つけました:1) stackoverflow.com/questions/5180327/… 2) stackoverflow.com/questions/4470107/… 私のキーフレームはH.264ビデオからのものであるため、2番目のリンクは正しくない可能性があります。
cnfcnf

回答:


6

「意味のある」はかなり主観的なものですが、「ぼやけた」ものはかなり客観的で検出が簡単です。

私は同様の問題を抱えていて、少し研究を重ねた結果、次のようなアルゴリズムになりました。

  • ビデオファイルの長さを秒単位で決定します。
  • ffmpegとシーンチェンジ検出を使用して10個のpngサムネイルを生成します。

    ffmpeg -ss {$skip} -i {$input} -vf "select=gt(scene\,0.3)" -r 1 -frames:v 1 {$output}
    

各繰り返しで $skip 秒単位でビデオの長さが10%増えます。パラメータ0.3はあなたにとって最も適切ではないかもしれませんが、あなたはそれと一緒にアラウンド再生することができます。これにより、重なり合うシーンや完全にぼやけた画像の問題が解決されました。

  • ImageMagickを使用すると、これら10個のサムネイルの端を検出して縮小し、パフォーマンスを向上させることができます。

    convert {$input} -thumbnail {$w}x{$h} -colorspace Gray -edge 1 {$path_to_downscaled_image}
    

私が使っている -thumbnail 画像を拡大縮小します。それから私は白黒フィルターを追加しています。最後に、半径1でエッジ検出を行います。これにより、エッジが白としてマークされた白黒画像のみが生成されます。これは、画像の白さが多いほど、エッジが多いことを意味します。あなたはこのようなものを得るでしょう:

enter image description here

  • ImageMagickで結果の白黒画像を識別します。

    identify -format '{$format}' {$path_to_downscaled_image}
    

興味があるのは、%[mean]と%[標準偏差]です。それらと一緒に遊んで、あなたに最適なものを見てください。例えば、全ての結果画像を "%[mean] +%[標準偏差]"でソートするだけです。サイズ変更とフィルタ処理を始める前に、同じ画像を見つけます。

  • 最後に、最も「エッジの効いた」ものを選び、そのオリジナルを見つけて、オプションでそれをもう一度変換します。

    convert {$input} -thumbnail {$w}x{$h} -adaptive-sharpen 1.25x0.75 {$final_output}
    

私はそれを見つけました -adaptive-sharpen それはそれらの同じエッジの周りでのみ画像をシャープにするので最終結果を本当に助けます。私はさまざまなジオメトリを試してみたところ、元の解像度の4分の1に縮小すると、1.25x0.75が最適であることがわかりました。

私はこれをPHPで行いましたが、12分の映画が実行されるのに約25秒かかりますが、これは私には問題ありません。

これが役に立ったことを願っています。


私はまだこれを試したことがありません、しかし論理は健全であるように思われます、そして、私は全体的にこれがどれほど徹底的であったかについて非常に感銘を受けます。ありがとうございました!
cnfcnf

試してみる。私はあなたの結果が何であるかを見るのをもっと幸せに思うでしょう。
matthewd
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.