Opencv读取视频获取的总帧数比实际少很多问题
问题描述
在读取一段从摄像头拉流保存下来的8分钟视频,opencv(opencv4.4)获取到的总帧数只有7帧,循环读取解码视频,获取到的帧数也只有7帧,明显此时存在问题
产生问题背景
opencv读取拉流视频,可能不同的解码器,会导致在调用opencv自身的解码器无法对视频进行解码,导致一部分帧解码失败,导致实际看到的帧数和读取到的帧数相差甚远
opencv视频解码code
import cv2
video_file = "Camera.mp4"
capture = cv2.VideoCapture(video_file) #读取视频或摄像
# Get Video info : resolution, fps, frame count
width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH)) #宽
height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)) #高
fps = int(capture.get(cv2.CAP_PROP_FPS)) #帧率
frame_count = int(capture.get(cv2.CAP_PROP_FRAME_COUNT)) #总帧数
print("video fps: %d, frame_count: %d,width: %d,height: %d" % (fps, frame_count,width,height))
frameNr = 0
while True:
ret, frame = capture.read() #opencv 读取到的视频帧默认是bgr
if not ret:
break
# frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) #图片bgr转换成rgb
cv2.imshow('demo', frame)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
frameNr = frameNr + 1
# 关闭视频文件
capture.release()
cv2.destroyAllWindows()
video fps: 25, frame_count: 6,width: 1920,height: 1080
解决办法
方法一:对视频通过ffmpeg解码
ffmpeg -i Camera_0420230221104457_20230221111458Centralized Storage.mp4 out.mp4
ffmpeg相关教程
方法二:使用imageio-ffmpeg读取视频,对视频进行解码
安装ffmpeg解码器
apt-get install ffmpeg
安装imageio-ffmpeg 包
pip install imageio-ffmpeg -i https://pypi.douban.com/simple
imageio视频解码code
import cv2
import numpy as np
import imageio
#pip install imageio-ffmpeg -i https://pypi.douban.com/simple
video_file = "Camera.mp4"
cap = imageio.get_reader(video_file, 'ffmpeg') #读取视频或摄像
fps = cap.get_meta_data()['fps'] #帧率
(width,height) = cap.get_meta_data()['size'] #size,(宽,高)
duration = cap.get_meta_data()['duration'] #时长
# frame_count = cap.count_frames() #总帧率 可以通过时长x帧率获取(存在异常AttributeError: 'Reader' object has no attribute 'count_frames')
frame_count = int(fps*duration) #总帧率 可以通过时长x帧率获取
print("video fps: %d, frame_count: %d,width: %d,height: %d" % (fps, frame_count,width,height))
for frameNr,frame in enumerate(cap): #imageio 读取到的视频帧默认是rgb
#image的类型是imageio.core.util.Image可用使用的下面这一注释行转换为arrary
#image = skimage.img_as_float(im).astype(np.float32)
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cv2.imshow('demo', frame_rgb)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
frameNr = frameNr + 1
# 关闭视频文件
cap.close()
video fps: 25, frame_count: 10814,width: 1920,height: 1080