最近在研究opencv,也就是cv2库,想实现开启摄像头实时显示画面+录像,从网上看了不少案例和代码,动手实践时发现很多案例和代码都没有经过严格验证,导致bug不断,生成的视频文件也不能播放。经过持续百度和摸索,已经成功修复所有bug。
bug1:运行时opencv报错 →fourcc参数格式必须是小写(*'mp4v'),用大写会有OpenCV报错
bug2:生成的视频size只有1kb,并且无法播放(qq影音) →frameSize的WIDTH/HEIGHT必须和摄 像头的逐帧分辨率一致
bug3:录制完成的视频播放时速度太快→用笔记本电脑验证,FPS<=6可以解bug,网上好多教程和案例里面FPS都是12、24,数值太高
如下为修复后的代码,可直接使用(网上案例太多,忘了是从哪儿抄的,如有侵权请联系):
import cv2
def captureVideoFromCamera():
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
#WIDTH/HEIGHT必须和摄像头逐帧捕获的分辨率一致,否则会生成1kb视频文件并且无法播放,by Navy 2022-03-31
#通过frame.shape获取摄像头逐帧分辨率,by Navy 2022-03-31
WIDTH = 640
HEIGHT = 480
FILENAME = r'd:\myvideo.MP4'
FPS = 24
cap.set(cv2.CAP_PROP_FPS, 24)
#如下fourcc参数必须是小写,用大写会有OpenCV报错,by Navy 2022-03-31
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(FILENAME, fourcc=fourcc, fps=FPS,frameSize=(WIDTH,HEIGHT))
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# 逐帧捕获
ret, frame = cap.read()
# 如果正确读取帧,ret为True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
#如下通过frame.shape获取摄像头逐帧分辨率,by Navy 2022-03-31
print(frame.shape)
#frame = cv2.flip(frame, 1) # 水平翻转
ret = out.write(frame)
#gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#gray = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
# 显示结果帧e
cv2.namedWindow('frame', cv2.WND_PROP_FULLSCREEN)#支持全屏,by Navy,2022.04.01
cv2.imshow('frame', frame)
if cv2.waitKey(1) == ord('q'): break
# 完成所有操作后,释放捕获器
out.release()
cap.release()
cv2.destroyAllWindows()
captureVideoFromCamera()