[经验]解决使用opencv 高分辨率下的摄像头卡顿不流畅
目录
- 发现
- 分析
- 解决
- 总结
发现
环境
- ubuntu 16.04
- python 2.7 (anaconda 的环境)
- cv 版本 3.4
- 安装方式 pip install opencv-contrib-python
问题
最近在做一个项目,需要使用opencv 打开摄像头,然后录制视频,在默认的参数下,opencv打开摄像头都是非常流畅的,但是在高分辨率下,摄像头使用如下的代码的时候就非常的不流畅,而且很卡,比如如下的代码做演示就非常的卡
import time
import numpy as np
import cv2
resv = (1920, 1080)
def show_video():
cap = cv2.VideoCapture(1)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
# cap.set(cv2.CAP_PROP_BUFFERSIZE,10)
while (True):
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
# gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
# print(frame.shape)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
在代码中,我设定了视频的分辨率为1080p , 这个时候演示出来的视频画面就非常的卡,是摄像头本身就不支持吗?我看了自己的设备参数 ,标明设备是支持1080p的
分析
我打开ubuntu系统的自带camera cheese
工具,不论是录制,还是拍摄,都是1080p无卡顿现象,这就说明本身不是设备的问题,这个时候我在想,是否有参数可以设置FPS,尝试在代码中加入
cap.set(cv2.CAP_PROP_FPS, 30)
将FPS设定在30帧,依然没有效果?难道是opencv的问题,尝试使用google 搜索关键字 opencv python set fps fake
得到答案
CV_CAP_PROP_FPS is a NOT a fake. See cap_libv4l.cpp(1) in OpenCV github repo. The key is to make sure, you use libv4l over v4l while configuring OpenCV. For that, before running cmake, install libv4l-dev
sudo apt-get install libv4l-dev
Now while configuring OpenCV with cmake, enable option, WITH_LIBV4L. If all goes good, in configuration status, you will see some thing similar to below
从答案里面得知,我们需要使用libv4l库,并且,在使用opencv 编译版本的时候,要开启这个feature ,很明显 ,当前我使用的opencv应该是直装版本,没有经过编译的,那知道问题在哪,我们进行尝试
解决
安装依赖项
sudo apt-get install libv4l-dev
下载opencv 源码
https://codeload.github.com/opencv/opencv/tar.gz/3.4.2 ,本次使用的3.4.2的版本
卸载之前的opencv
pip uninstall opencv-contrib-python
编译opencv
进入opencv 目录
mkdir build
cd build
cmake -D WITH_LIBV4L=ON ../
make -j8
make install
ldconfig
cp lib/cv2.so /home/bruce/miniconda2/lib/python2.7/site-packages # 注意,这里是当前使用的python环境
验证
这次使用的是录制视频并输出视频的代码
def simple_video(minutes=5):
start = int(time.time())
cap = cv2.VideoCapture(1)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
cap.set(cv2.CAP_PROP_FPS, 25)
# cap.set(cv2.CV_CAP_PROP_BUFFERSIZE, 20)
# Define the codec and create VideoWriter objectXVID
# fourcc = cv2.VideoWriter_fourcc(*'XVID')
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('{}.avi'.format(str(start)), fourcc, 25.0, (1920, 1080))
while (cap.isOpened()):
step = int(time.time())
ret, frame = cap.read()
if ret == True:
frame = cv2.flip(frame, 0)
# img = cv2.resize(frame,(1920,1080))
# write the flipped frame
out.write(frame)
cv2.imshow('frame', frame)
if (cv2.waitKey(1) & 0xFF == ord('q')) or ((step - start) >= minutes * 60):
print("enter to the time used")
break
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
simple_video(1)
录制了1分钟的视频,看了一下结果,还不错,非常流畅,成功解决这个问题
总结
这次我们主要从,发现问题,假设问题,搜索问题的几个角度 来成功解决我们在工程上的一些问题,突破点就是验证自己的想法,使用正常的关键字去寻找问题的答案,OK,这次的分享就到这里
参考文档:
- 原文作者:大鱼
- 原文链接:https://brucedone.com/archives/1193/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。