与えられたビデオから、おそらく最も多様性とシーンのある10フレームを選択しようとしています。さまざまな選択シナリオを試してみたいと思いますが、I-frame
の概念は本質的にシーンの変更を意味するというのは良いことです!だから私はIフレームを取得したいと思います。しかし、多分Iフレームがたくさんあるので、おそらくそれらをサンプリングする必要があります。
FFMpegまたはPythonのビデオですべてのIフレームのframe_numberのリストを取得するにはどうすればよいですか?リストを使用して、そのうちの10個だけを選択し、PNG/JPEGとして保存したいと思います。
ここから洞察を得て、私はffprobe
でそれを行うことができました:
def iframes():
if not os.path.exists(iframe_path):
os.mkdir(iframe_path)
command = 'ffprobe -v error -show_entries frame=pict_type -of default=noprint_wrappers=1'.split()
out = subprocess.check_output(command + [filename]).decode()
f_types = out.replace('pict_type=','').split()
frame_types = Zip(range(len(f_types)), f_types)
i_frames = [x[0] for x in frame_types if x[1]=='I']
if i_frames:
cap = cv2.VideoCapture(filename)
for frame_no in i_frames:
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_no)
ret, frame = cap.read()
outname = iframe_path+'i_frame_'+str(frame_no)+'.jpg'
cv2.imwrite(outname, frame)
cap.release()
print("I-Frame selection Done!!")
if __name__ == '__main__':
iframes()
これはX/Yの問題のように思われるので、いくつかの異なるコマンドを提案します。
各キーフレームのタイムスタンプのリストを出力する場合:
ffprobe -v error -skip_frame nokey -show_entries frame=pkt_pts_time -select_streams v -of csv=p=0 input
0.000000
2.502000
3.795000
6.131000
10.344000
12.554000
-skip_frame nokey
に注意してください。
もう1つの方法は、 select filter をscene
オプションとともに使用して、サムネイルを出力することです。
ffmpeg -i input -vf "select=gt'(scene,0.4)',scale=160:-1" -vsync vfr %04d.png
これにより、すべてのiフレームがPNG画像として出力されます。
ffmpeg -i 2.flv -vf "select=eq(pict_type\,I)" -vsync vfr frame-%02d.png
このコメントのクレジットは、同様のsuperuser.comの質問です。 ビデオクリップからすべてのキーフレームを抽出する方法は?
お役に立てば幸いです。乾杯。
イアン