为了在radxa 3W上使用opencv调用摄像头并用Gstream推流出去,需要编译安装opencv,为什么不使用pip直接安装编译好的opencv呢,因为我试过,它默认不带Gstreamer,只支持ffmpeg。虽然ffmpeg也能推流,但是经过我的测试还是gstreamer的延迟低一些。
提示:我是直接在rk3566上进行编译的,不想折腾交叉编译
我的radxa 3E的内存是2Gb,编译opencv4.11版本的时候出现了内存占满的问题,导致编译过程卡住,我换成radxa 3W之后(8G)就可以正常编译了,我观察出来,安全内存应该是4G。但是编译opencv3.5版本的2G内存也是编译通过了的。
没有安装cmake和gcc就先安装
sudo apt update
sudo apt install cmake
sudo apt install build-essential
sudo apt-get install python3-dev #python相关的头文件也装一下
pip3 install numpy
安装gstreamer
这个很简单,直接sudo apt安装即可。
#安装编译依赖
sudo apt-get update
sudo apt-get install -y
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
libv4l-dev v4l-utils libopenblas-dev
libgtk2.0-dev libavcodec-dev libavformat-dev
libswscale-dev libtbb2 libtbb-dev libjpeg-dev
libpng-dev libtiff-dev libdc1394-22-dev
安装V4L(摄像头驱动)
已经在上面的命令行包含了。V4L是摄像头驱动,GTK是图形界面。
安装opencv
这个建议直接去github下载源码包,找到自己想要的版本即可,下载opencv和opencv_contrib,他们分别是基础功能包和扩展功能包,跟踪算法那些就在扩展功能包里面。
进入解压后的opencv包
cd opencv-3.4.15
mkdir build //单独建一个编译文件夹
cmake \-D CMAKE_BUILD_TYPE=RELEASE \-D CMAKE_INSTALL_PREFIX=/usr/local \-D INSTALL_PYTHON_EXAMPLES=ON \-D INSTALL_C_EXAMPLES=OFF \
-D OPENCV_ENABLE_NONFREE=ON \-D WITH_GSTREAMER=ON \-D GSTREAMER_INCLUDE_DIRS=/usr/include/gstreamer-1.0/ \-D GSTREAMER_LIBRARIES=/usr/lib/aarch64-linux-gnu/libgstreamer-1.0.so \
-D WITH_V4L=ON \-D WITH_LIBV4L=ON \-D BUILD_opencv_python3=ON \-D BUILD_opencv_python2=OFF \-D PYTHON3_EXECUTABLE=$(which python3) \
-D PYTHON3_INCLUDE_DIR=$(python3 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \
-D PYTHON3_NUMPY_INCLUDE_DIRS=$(python3 -c "import numpy; print(numpy.get_include())") \
-D BUILD_EXAMPLES=OFF \-D BUILD_opencv_tracking=ON \-D OPENCV_EXTRA_MODULES_PATH=/home/radxa/opencv/opencv_contrib-3.4.15/modules \
-D BUILD_TESTS=OFF \-D BUILD_PERF_TESTS=OFF \-D BUILD_DOCS=OFF \..
更新一个4.11版本的,这个在cmzhe给ake时会下载wechat_qrcode,很容易下载失败,如果不要这个包的话可以去源码下把它删了,在contrib下的modules下的wechat_qrcode.
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_PYTHON_EXAMPLES=ON -D INSTALL_C_EXAMPLES=OFF -D WITH_GSTREAMER=ON -D GSTREAMER_INCLUDE_DIRS=/usr/include/gstreamer-1.0/ -D GSTREAMER_LIBRARIES=/usr/lib/aarch64-linux-gnu/libgstreamer-1.0.so -D WITH_RKMPP=ON -D RKMPP_INCLUDE_DIR=/usr/include/rockchip/ -D RKMPP_LIBRARY=/usr/lib/aarch64-linux-gnu/librockchip_mpp.so -D WITH_RGA=ON -D RGA_INCLUDE_DIR=/usr/include/rga/ -D RGA_LIBRARY=/usr/lib/aarch64-linux-gnu/librga.so -D WITH_FFMPEG=ON -D WITH_VA=ON -D WITH_LIBV4L=ON -D GSTREAMER_PLUGIN_RKMPP=ON -D WITH_VULKAN=ON -D WITH_OPENCL=ON -D BUILD_opencv_python3=ON -D BUILD_opencv_python2=OFF -D PYTHON3_EXECUTABLE=$(which python3) -D PYTHON3_INCLUDE_DIR=$(python3 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") -D PYTHON3_NUMPY_INCLUDE_DIRS=$(python3 -c "import numpy; print(numpy.get_include())") -D ENABLE_NEON=ON -D CPU_BASELINE='NEON' -D WITH_LAPACK=ON -D OPENCV_EXTRA_MODULES_PATH=/home/radxa/opencv/opencv_contrib-4.11.0/modules -D BUILD_EXAMPLES=OFF -D BUILD_opencv_tracking=ON -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_DOCS=OFF -DOPENCV_ENABLE_NONFREE=OFF ..
复制这一串cmake粘贴进终端,然后回车执行,如果有报错就调整一下格式。
这一串的作用是,CMAKE_INSTALL_PREFIX 编译后 make install 时的安装路径,如果指定安装路径以后可以在这个路径下复制整体文件到其他板子上用。WITH_GSTREAMER字面意思,打开gstreamer。GSTREAMER_INCLUDE_DIRS=/usr/include/gstreamer-1.0/ -D GSTREAMER_LIBRARIES=/usr/lib/aarch64-linux-gnu/libgstreamer-1.0.so这个需要注意一下,我安装后cmake自己找不到gstreamer安装库的路径,所以我手动添加了,如果你也是radxa,我估计路径是一致的。OPENCV_EXTRA_MODULES_PATH其他模块路径,就是刚才下载的opencv_contrib,路径要到modules。其它指令都是字面意思。
不出意外cmake后长这个样子,一定要检查gstreamer那里是不是yes,不然等下编译就是白编译了。看你需要的模块是不是都是yes。
-- Applications: apps
-- Documentation: NO
-- Non-free algorithms: YES
--
-- GUI:
-- GTK+: YES (ver 3.24.24)
-- GThread : YES (ver 2.66.8)
-- GtkGlExt: NO
-- VTK support: NO
--
-- Media I/O:
-- ZLib: /usr/lib/aarch64-linux-gnu/libz.so (ver 1.2.11)
-- JPEG: /usr/lib/aarch64-linux-gnu/libjpeg.so (ver 62)
-- WEBP: build (ver encoder: 0x020f)
-- PNG: /usr/lib/aarch64-linux-gnu/libpng.so (ver 1.6.37)
-- TIFF: /usr/lib/aarch64-linux-gnu/libtiff.so (ver 42 / 4.2.0)
-- JPEG 2000: build (ver 1.900.1)
-- OpenEXR: build (ver 2.3.0)
-- HDR: YES
-- SUNRASTER: YES
-- PXM: YES
--
-- Video I/O:
-- DC1394: YES (ver 2.2.6)
-- FFMPEG: YES
-- avcodec: YES (ver 58.91.100)
-- avformat: YES (ver 58.45.100)
-- avutil: YES (ver 56.51.100)
-- swscale: YES (ver 5.7.100)
-- avresample: NO
-- GStreamer: YES
-- base: YES (ver 1.18.5)
-- video: YES (ver 1.18.5)
-- app: YES (ver 1.18.5)
-- riff: YES (ver 1.18.5)
-- pbutils: YES (ver 1.18.5)
-- libv4l/libv4l2: 1.20.0 / 1.20.0
-- v4l/v4l2: linux/videodev2.h
--
-- Parallel framework: pthreads
--
-- Trace: YES (with Intel ITT)
--
-- Other third-party libraries:
-- Lapack: NO
-- Eigen: YES (ver 3.3.9)
-- Custom HAL: YES (carotene (ver 0.0.1))
-- Protobuf: build (3.5.1)
--
-- OpenCL: YES (no extra features)
-- Include path: /home/radxa/opencv/opencv-3.4.15/3rdparty/include/opencl/1.2
-- Link libraries: Dynamic load
--
-- Python 3:
-- Interpreter: /usr/bin/python3 (ver 3.9.2)
-- Libraries: /usr/lib/aarch64-linux-gnu/libpython3.9.so (ver 3.9.2)
-- numpy: /usr/lib/python3/dist-packages/numpy/core/include (ver 1.19.5)
-- install path: lib/python3.9/dist-packages/cv2/python-3.9
--
-- Python (for build): /usr/bin/python3
--
-- Java:
-- ant: NO
-- JNI: NO
-- Java wrappers: NO
-- Java tests: NO
--
-- Install to: /usr/local
然后就
make -j3
我尝试过make -j8,编译速度会快些,但是后期编译的时候会内存不足,导致板子卡死,我的内存是2G。
编译完成后
sudo make install
然后写一个python文件检查一下gstreamer是否安装成功。
import cv2
print(cv2.getBuildInformation())
测试结果
radxa@radxa-zero3:~/demo/opencvdemo$ python3 test.py
General configuration for OpenCV 3.4.15 =====================================
Version control: unknown
Extra modules:
Location (extra): /home/radxa/opencv/opencv_contrib-3.4.15/modules
Version control (extra): unknown
Platform:
Timestamp: 2025-02-18T02:01:28Z
Host: Linux 5.10.160-39-rk356x aarch64
CMake: 3.24.2
CMake generator: Unix Makefiles
CMake build tool: /usr/bin/gmake
Configuration: RELEASE
CPU/HW features:
Baseline: NEON FP16
C/C++:
Built as dynamic libs?: YES
C++11: YES
C++ Compiler: /usr/bin/c++ (ver 10.2.1)
C++ flags (Release): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG -DNDEBUG
C++ flags (Debug): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -g -O0 -DDEBUG -D_DEBUG
C Compiler: /usr/bin/cc
C flags (Release): -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -O3 -DNDEBUG -DNDEBUG
C flags (Debug): -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -g -O0 -DDEBUG -D_DEBUG
Linker flags (Release): -Wl,--gc-sections -Wl,--as-needed
Linker flags (Debug): -Wl,--gc-sections -Wl,--as-needed
ccache: NO
Precompiled headers: NO
Extra dependencies: dl m pthread rt
3rdparty dependencies:
OpenCV modules:
To be built: aruco bgsegm bioinspired calib3d ccalib core datasets dnn dnn_objdetect dpm face features2d flann freetype fuzzy hfs highgui img_hash imgcodecs imgproc line_descriptor ml objdetect optflow phase_unwrapping photo plot python3 reg rgbd saliency shape stereo stitching structured_light superres surface_matching text tracking video videoio videostab xfeatures2d ximgproc xobjdetect xphoto
Disabled: world
Disabled by dependency: -
Unavailable: cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev cvv hdf java matlab ovis python2 sfm ts viz
Applications: apps
Documentation: NO
Non-free algorithms: YES
GUI:
GTK+: YES (ver 3.24.24)
GThread : YES (ver 2.66.8)
GtkGlExt: NO
VTK support: NO
Media I/O:
ZLib: /usr/lib/aarch64-linux-gnu/libz.so (ver 1.2.11)
JPEG: /usr/lib/aarch64-linux-gnu/libjpeg.so (ver 62)
WEBP: build (ver encoder: 0x020f)
PNG: /usr/lib/aarch64-linux-gnu/libpng.so (ver 1.6.37)
TIFF: /usr/lib/aarch64-linux-gnu/libtiff.so (ver 42 / 4.2.0)
JPEG 2000: build (ver 1.900.1)
OpenEXR: build (ver 2.3.0)
HDR: YES
SUNRASTER: YES
PXM: YES
Video I/O:
DC1394: YES (ver 2.2.6)
FFMPEG: YES
avcodec: YES (ver 58.91.100)
avformat: YES (ver 58.45.100)
avutil: YES (ver 56.51.100)
swscale: YES (ver 5.7.100)
avresample: NO
GStreamer: YES
base: YES (ver 1.18.5)
video: YES (ver 1.18.5)
app: YES (ver 1.18.5)
riff: YES (ver 1.18.5)
pbutils: YES (ver 1.18.5)
libv4l/libv4l2: 1.20.0 / 1.20.0
v4l/v4l2: linux/videodev2.h
Parallel framework: pthreads
Trace: YES (with Intel ITT)
Other third-party libraries:
Lapack: NO
Eigen: YES (ver 3.3.9)
Custom HAL: YES (carotene (ver 0.0.1))
Protobuf: build (3.5.1)
OpenCL: YES (no extra features)
Include path: /home/radxa/opencv/opencv-3.4.15/3rdparty/include/opencl/1.2
Link libraries: Dynamic load
Python 3:
Interpreter: /usr/bin/python3 (ver 3.9.2)
Libraries: /usr/lib/aarch64-linux-gnu/libpython3.9.so (ver 3.9.2)
numpy: /usr/lib/python3/dist-packages/numpy/core/include (ver 1.19.5)
install path: lib/python3.9/dist-packages/cv2/python-3.9
Python (for build): /usr/bin/python3
Java:
ant: NO
JNI: NO
Java wrappers: NO
Java tests: NO
Install to: /usr/local
-----------------------------------------------------------------
完成!
提示:如果结果gstreamer那里不是yes,查看输出的opencv版本是不是你安装的那个版本,如果不是极有可能是你通过apt install python3-opencv的opencv版本没有卸载掉,把它卸载掉再测试就好了。
附上测试代码,搞了好久,代码是deepseek生成的,主要是Gstreamer部分难搞,该代码通过opencv将摄像头视频流用gstreamer推送到UDP。RGB转NV12部分如果需要使用opencv实现的话需要安装4.5版本的opencv。
import cv2
import gi
import numpy as np
import datetime
import time # 新增时间模块用于计算帧率
gi.require_version('Gst', '1.0')
gi.require_version('GstApp', '1.0')
from gi.repository import Gst, GstApp
Gst.init(None)
# 摄像头配置
CAM_DEVICE = "/dev/video0"
CAM_WIDTH = 640
CAM_HEIGHT = 480
UDP_IP = "127.0.0.1"
UDP_PORT = 5600
# 输入管道
gst_capture = (
f"v4l2src device={CAM_DEVICE} ! "
f"video/x-raw,format=NV12,width={CAM_WIDTH},height={CAM_HEIGHT},framerate=30/1 ! "
"videoconvert ! video/x-raw,format=BGR ! appsink"
)
output_pipeline = Gst.parse_launch(
f'appsrc name=source caps="video/x-raw,format=BGR,width={CAM_WIDTH},height={CAM_HEIGHT},framerate=30/1" ! '
'videoconvert ! video/x-raw,format=NV12 ! '
'queue ! '
'mpph265enc bps=1000000 rc-mode=vbr gop=30 ! '
'h265parse ! '
'rtph265pay config-interval=1 ! '
f'udpsink host={UDP_IP} port={UDP_PORT} '
)
appsrc = output_pipeline.get_by_name('source')
output_pipeline.set_state(Gst.State.PLAYING)
# 帧率计算初始化
prev_time = time.time()
avg_fps = 0.0
ALPHA = 0.1 # 平滑系数
try:
cap = cv2.VideoCapture(gst_capture, cv2.CAP_GSTREAMER)
if not cap.isOpened():
raise RuntimeError("无法打开摄像头输入")
while True:
ret, frame = cap.read()
if not ret:
print("帧读取失败")
break
if frame is None or frame.size == 0:
print("无效帧数据")
continue
# ========== 帧率计算 ==========
current_time = time.time()
dt = current_time - prev_time
prev_time = current_time
fps = 1 / dt
avg_fps = ALPHA * fps + (1 - ALPHA) * avg_fps # 指数平滑
# ========== 文字叠加处理 ==========
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 0.8
thickness = 2
line_type = cv2.LINE_AA
# 时间戳(左上角)
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
cv2.putText(frame, f"Time: {timestamp}",
(10, 30), font, font_scale, (0, 255, 0), thickness, line_type)
# 实时帧率(右上角)
fps_text = f"FPS: {avg_fps:.2f}"
text_size = cv2.getTextSize(fps_text, font, font_scale, thickness)[0]
cv2.putText(frame, fps_text,
(frame.shape[1] - text_size[0] - 10, 30),
font, font_scale, (255, 0, 0), thickness, line_type)
# ========== 格式转换和推送 ==========
data = frame.tobytes()
buffer = Gst.Buffer.new_wrapped(data)
appsrc.emit('push-buffer', buffer)
except KeyboardInterrupt:
print("用户中断")
except Exception as e:
print(f"发生错误: {str(e)}")
finally:
cap.release()
appsrc.emit('end-of-stream')
output_pipeline.set_state(Gst.State.NULL)
Gst.deinit()
更新
如果报错
radxa@radxa-zero3:~/demo$ python3 gs.py
Traceback (most recent call last):
File "/home/radxa/demo/gs.py", line 1, in <module>
import cv2
ModuleNotFoundError: No module named 'cv2'
检查一下是不是cmake的时候python没有绑定,我就光看gstreamer有没有开启没有管python导致opencv和python没有绑定,查找不到cv2*.so的文件。如果不是这个问题就是python路径设置不对,这个只需要在环境变量中设置一下就行了。
-- Python 3:
-- Interpreter: /usr/bin/python3 (ver 3.9.2)
-- Libraries: /usr/lib/aarch64-linux-gnu/libpython3.9.so (ver 3.9.2)
-- Limited API: NO
-- numpy: /usr/lib/python3/dist-packages/numpy/core/include (ver 1.19.5)
-- install path: lib/python3.9/site-packages/cv2/python-3.9
查看是否安装了cv2.so
sudo find /usr/local/ -name "cv2*.so"
有路径输出说明是绑定成功的,只是路径不对。
/usr/local/lib/python3.9/site-packages/cv2/python-3.9/cv2.cpython-39-aarch64-linux-gnu.so
然后只需要设置环境变量就行了。
export PYTHONPATH=/usr/local/lib/python3.9/site-packages:$PYTHONPATH
永远生效可以写在~ /.bashrc下:
vim ~/.bashrc #在最后面添加上面那行指令
source ~/.bashrc