前言
为了对视频做一些处理,需要提取视频中的图像,根据不同需求有时候可能需要按一定时间间隔或帧间隔来提取视频中的帧,目的是为了处理提高效率和减少内存的占用,使用OpenCV也可以完成这一功能,不过相对于FFmpeg来说,处理视频的效率要慢不少,对于数量比较大的视频处理建议使用FFmpeg来进行。
通过FFmpeg获取视频的总帧数
ffprobe <input> -select_streams v -show_entries stream=nb_frames -of default=nk=1:nw=1 -v quiet
通过FFmpeg获取视频的总时长
ffprobe <input> -select_streams v -show_entries stream=duration -of default=nk=1:nw=1 -v quiet
按间隔帧来提取视频中的帧
ffmpeg -i 10021502.mp4 -vf "select=between(n\,84\,208)*not(mod(n\,4))" -vsync 0 ./pkl/image_%05d.jpg
主体是一个select 的过滤语句:
其中:between(n,*) 是指 从第几帧到第几帧之间进行提取...
not(mode(n\, K))是指每隔几帧输出一帧。
使用between可以指定需要提取开始帧和结束帧的位置,如果想要对视频中所有的帧进行间隔采样,命令如下
command_extract = "select=(gte(n\,%d))*not(mod(n\,%d))"%(60,60)
com_str = 'ffmpeg -i ' + video_path + ' -vf "%s" -vsync 0 '%command_extract + save_jpg_tmp_path + '/%06d.jpg'
command_extract中的60指的是间隔的帧数,video_path指的是视频的路径,save_jpg_tmp_path指的是导出视频中的图片存放的路径
按时间间隔取帧
ffmpeg -i <input> -vf "select=(gte(t\,120))*(isnan(prev_selected_t)+gte(t-prev_selected_t\,120))" -vsync 0 image_%05d.jpg
上面命令中的120的单位是s,指每120s提取视频中的一帧图像
参考:
https://blog.csdn.net/sparkexpert/article/details/83891389
https://stackoverflow.com/questions/32043680/ffmpeg-select-frames-at-position-of-video