web-dev-qa-db-ja.com

サムネイルの選択にはffmpegを使用します

これは [〜#〜] here [〜#〜] からのフォローアップの質問です。 kとそのnフィルターを使用して、特定のビデオのFFMpegフレーム数からthumbnailフレームをサンプリングしたいと思います。投稿があります ここ意味のあるフレームを選択する方法についての洞察を提供します。ただし、その質問では、シーンの変化が%40しきい値よりも高いものを選択する必要がありました。私の場合、それは反対です。以前のシーンと比較して最も低いシーンの変化があるフレームを選択する必要があると思います(通常、何かに焦点が合っているビデオでは、シーンはより安定していてカメラですあまり動かない)。

FFMpegでこれを行う方法は?フレームをクラスター化して代表者を選ぶこともできますか?

1
Tina J

サムネイルフィルターの基本的なコマンドは

ffmpeg -i in.mp4 -vf thumbnail=n=100 -vsync 0 -frame_pts 1 out%d.png

これにより、100フレームごとに1つの代表的なフレームが選択されます。

-vsync 0はソースのタイムスタンプを保持します。

-frame_pts 1は、そのタイムスタンプを出力ファイル名にエンコードします。したがって、ビデオが24 fpsで、出力ファイル名がout322.pngの場合、そのフレームはビデオのタイムスタンプ322/24 = 13.41sから取得されます。


これらは、フィルターの関連関数です。

フィルタは、パックされた8ビットRGBピクセルフレームで機能します。

R1G1B1R2G2B2R3G3B3...

各フレームのヒストグラムは次のように計算されます。

// update current frame RGB histogram
for (j = 0; j < inlink->h; j++) {
    for (i = 0; i < inlink->w; i++) {
        hist[0*256 + p[i*3    ]]++;
        hist[1*256 + p[i*3 + 1]]++;
        hist[2*256 + p[i*3 + 2]]++;
    }
    p += frame->linesize[0];
}

ピクセルごとに、3つの配列要素の値が増分されます。それらのインデックスは、それらのピクセルコンポーネントのカラー値(上記のデータレイアウトに従って調整)です。

次に、クラスターの平均ヒストグラムが計算されます。

// average histogram of the N frames
for (j = 0; j < FF_ARRAY_ELEMS(avg_hist); j++) {
    for (i = 0; i < nb_frames; i++)
        avg_hist[j] += (double)s->frames[i].histogram[j];
    avg_hist[j] /= nb_frames;
}

コンポーネントの色の値ごとに、すべてのフレームでのカウントが平均化されます。

次に、「最良の」フレームが選択されます。

// find the frame closer to the average using the sum of squared errors
for (i = 0; i < nb_frames; i++) {
    sq_err = frame_sum_square_err(s->frames[i].histogram, avg_hist);
    if (i == 0 || sq_err < min_sq_err)
        best_frame_idx = i, min_sq_err = sq_err;
}

ここで、二乗誤差の合計は次のとおりです。

for (i = 0; i < HIST_SIZE; i++) {
    err = median[i] - (double)hist[i];
    sum_sq_err += err*err;
}

HIST_SIZE = 3 x 256 = 768。

2
Gyan