OpenCV读取视频时会自动丢掉重复帧,导致读取到的帧数和视频里的实际总帧数不一致,比如说你用视频标注工具打开视频看到视频总共有855帧,可是使用OpenCV的VideoCapture类的read()能读出来的总是只能最多读到847帧,好像后面的8帧丢了,其实这并不是最后面的8帧有问题读不出来,而是OpenCV自动将视频中的所有重复的8帧丢掉了,而不一定是将最后的8帧丢了。
如果一定要读取出全部的帧,得借助ffmpeg,方法一当然是先安装ffmpeg,然后手工执行ffmpeg命令来抽取出全部帧,办法二是在安装了ffmeg基础上继续安装ffmpy包,使用ffmpy也就是ffmpeg python api来写python程序来读取出全部帧,办法三在安装了ffmpeg基础上继续安装sk-video包,使用skvideo的api写python程序来读取出全部的帧。
ffmpeg可以在官网上直接下载对应操作系统版本的已编译好的程序,然后将ffmpeg所在的bin的路径加入到OS的path路径即可,如果是Ubuntu,想使用apt安装,可以使用下面的办法安装:
sudo add-apt-repository ppa:kirillshkrogalev/ffmpeg-next
sudo apt-get update
sudo apt-get install ffmpeg
安装ffmpy包(关于ffmpy的用法,参考官方文档 https://ffmpy3.readthedocs.io/en/latest/):
pip install ffmpy
安装sk-video包:
pip install sk-video
然后在代码中
import skvideo.io
#...
imgarray = skvideo.io.vread(video_file)
for frame in imgarray:
#...
注意要import skvideo.io,而不是import skvideo,否则报错:
Traceback (most recent call last):
File "cie2voc2007.py", line 150, in
convert(src_path,dest_path)
File "cie2voc2007.py", line 118, in convert
imgarray = skvideo.io.vread(video_file)
AttributeError: module 'skvideo' has no attribute 'io'
我查看了一下原因,其实C:\Python38\lib\site-packages\skvideo\下io文件夹是肯定存在的,为何还报错呢,看了一下skvideo下的__init__.py这个文件的内容,它并没有import io,所以报上面的错误。