使用 Opencv 加速从摄像头读取视频帧
Posted
技术标签:
【中文标题】使用 Opencv 加速从摄像头读取视频帧【英文标题】:Speed up reading video frames from camera with Opencv 【发布时间】:2021-01-06 07:38:51 【问题描述】:目前,我在 Python 中实现了我的应用程序,以通过 USB 读取相机帧。我使用 Opencv,但对于 60fps 和 1920x1080 分辨率的相机,我无法捕捉到这个速度。我尝试了一些东西:cv2.VideoCapture(0, cv2.CAP_FFMPEG),但我无法获取帧(捕获读取返回 False)。您能否提出任何解决方案或方法来提高整体速度甚至在 GPU 中处理它们。
# Opencv 3.4.9 & Python 3.6.9
import cv2
capture = cv2.VideoCapture(0, cv2.CAP_FFMPEG)
while True:
ret, frame = capture.read()
if ret:
cv2.imshow('Demo', frame)
cv2.waitKey(1)
Opencv 是从源代码构建的:
#!/usr/bin/env bash
set -e
VERSION='3.4.9'
DOWNLOAD_URL="https://github.com/opencv/opencv/archive/$VERSION.zip"
CONTRIB_DOWNLOAD_URL="https://github.com/opencv/opencv_contrib/archive/$VERSION.zip"
CURRENT_DIR="$(pwd)"
config_opencv_with_cuda()
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D WITH_CUDA=ON \
-D ENABLE_FAST_MATH=1 \
-D CUDA_FAST_MATH=1 \
-D WITH_CUBLAS=1 \
-D WITH_V4L=ON \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=ON \
-D BUILD_opencv_cnn_3dobj=OFF \
-D BUILD_opencv_dnn_modern=OFF \
-D OPENCV_EXTRA_MODULES_PATH=$CURRENT_DIR/opencv_contrib-$VERSION/modules \
-D BUILD_DOCS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_EXAMPLES=OFF ..
echo 'Uninstalling pip installation'
pip3 uninstall opencv-python opencv-contrib-python
echo 'Installing dependencies'
apt-get update && apt-get install -y \
build-essential cmake pkg-config \
libjpeg-dev libtiff5-dev libpng12-dev \
libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
libxvidcore-dev libx264-dev \
libgtk2.0-dev libgtk-3-dev \
gfortran
wget -O opencv.zip "$DOWNLOAD_URL"
wget -O opencv_contrib.zip "$CONTRIB_DOWNLOAD_URL"
unzip opencv.zip && unzip opencv_contrib.zip
cd opencv-$VERSION
mkdir build
cd build
if [[ -d /usr/local/cuda ]]; then
config_opencv_with_cuda
else
config_opencv_without_cuda
fi
make -j $(nproc)
make install
ldconfig
【问题讨论】:
yozr 代码长什么样子? @Micka 请检查我上面的代码,很简单 您可以尝试删除 imshow 和 waitkey 并仅计算帧数和秒数吗?对于 60 fps,可能需要使用更快的异步图像显示。您在哪种设备上运行代码?一帧的所有处理时间只有 17 毫秒! @Micka 我知道这个例子的 imshow 效果,但我想尝试更改为 opencv 的 ffmpeg 后端,但我得到的是 VideoCapture 总是返回 False,我无法使用 cv2 获取帧.VideoCapture(0, cv2.CAP_FFMPEG) 抱歉,不知道 ffnpeg videocapture 是否适用于所有情况。目前您的问题标题具有误导性。 【参考方案1】:您无法捕捉到这种速度的原因是VideoCapture
阻塞了应用程序,而下一帧正在被读取、解码和返回。
如果我没记错的话,您正在从 USB 读取电影文件。
您可以使用FileVideoStream
对象来加速您的帧。 FileVideoStream
使用queue
结构进行读取、解码和返回。因此,应用程序在处理过程中不会被阻塞。
你需要安装imutils
pip install imutils
蟒蛇:conda install -c conda-forge imutils
示例用法:
import cv2
from imutils.video import FileVideoStream as Fvs
fvs = Fvs(path="usb.mp4").start()
four_cc = cv2.VideoWriter_fourcc(*"mp4v")
writer = cv2.VideoWriter("out.mp4", four_cc, 60,
(1920, 1080), isColor=True)
while True:
frame = fvs.read()
# You write your processing code below here
# If you are sure each usb frame size is (1920, 1080) comment the below state.
frame = cv2.resize(frame, (1920, 1080))
writer.write(frame)
cv2.imshow("out", frame)
if cv2.waitKey(0) & 0xFF == ord("q"):
break
cv2.destroyAllWindows()
fvs.stop()
writer.release()
【讨论】:
感谢您的回答,但是如何使 cv2 VideoCapture 与 FFMPEG 后端一起工作? 好吧,如果您打算使用 VideoCapture,您将来会遇到速度问题。因此我写了这个答案以上是关于使用 Opencv 加速从摄像头读取视频帧的主要内容,如果未能解决你的问题,请参考以下文章