在嵌入式开发中,尤其是在 Petalinux 平台上,经常需要使用 OpenCV 进行图像处理和计算机视觉相关的任务。然而,直接使用 apt-get 安装 OpenCV 往往不可行,原因在于交叉编译环境的复杂性和版本兼容性问题。因此,手动编译 OpenCV 4.1.0 源码,生成 ARM64 动态库 (.so),然后在 Petalinux 中打包使用,成为一种常见的解决方案。本文将详细介绍如何进行手动编译以及在 Petalinux 中集成的过程。
准备工作
交叉编译工具链
确保已经安装了适用于 ARM64 架构的交叉编译工具链。通常,Xilinx 提供的 SDK 包含所需的工具链。可以通过设置环境变量 ARCH 和 CROSS_COMPILE 来指定编译器。
export ARCH=aarch64
export CROSS_COMPILE=aarch64-linux-gnu-
下载 OpenCV 4.1.0 源码
从 OpenCV 官网或 GitHub 下载 OpenCV 4.1.0 的源码包。
安装依赖库
在编译 OpenCV 之前,需要安装一些必要的依赖库。这些库包括但不限于:
- CMake (3.15 或更高版本)
- pkg-config
- zlib
- libjpeg
- libpng
- libtiff
- libjasper
- libavcodec
- libavformat
- libswscale
- libv4l
使用 apt-get 安装这些依赖库:
sudo apt-get update
sudo apt-get install -y cmake pkg-config zlib1g-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
编译 OpenCV 4.1.0
配置编译选项
使用 CMake 配置 OpenCV 的编译选项。创建一个 build 目录,并在该目录下执行 CMake 命令。
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D CMAKE_TOOLCHAIN_FILE=../opencv/platforms/linux/arm64-gnu-linux.toolchain.cmake \
-D WITH_LIBV4L=ON \
-D BUILD_TIFF=ON \
-D BUILD_JPEG=ON \
-D BUILD_PNG=ON \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_python3=OFF \
-D ENABLE_NEON=ON \
-D ENABLE_VFPV3=ON \
-D WITH_TBB=OFF \
-D WITH_OPENCL=OFF \
-D WITH_CUDA=OFF \
-D WITH_VTK=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
../opencv
注意:CMAKE_TOOLCHAIN_FILE 需要指向 OpenCV 源码中的 ARM64 工具链文件。根据实际情况修改路径。WITH_LIBV4L=ON 启用 V4L 支持,用于摄像头操作。关闭 Java 和 Python 绑定可以减少编译时间,并避免一些潜在的依赖问题。关闭 TBB、OpenCL、CUDA 和 VTK 等不必要的模块,可以进一步缩小库的大小。
开始编译
使用 make 命令开始编译。
make -j4 # 使用 4 个线程进行编译,根据 CPU 核心数调整
安装 OpenCV
编译完成后,使用 make install 命令安装 OpenCV。
sudo make install
这将把编译好的动态库和头文件安装到 /usr/local 目录下。
在 Petalinux 中打包 OpenCV 动态库
创建 Petalinux 应用
使用 Petalinux 工具创建一个新的应用。例如:
petalinux-create -t apps --template c --name opencv_test
cd opencv_test/src
复制 OpenCV 动态库和头文件
将编译好的 OpenCV 动态库 (/usr/local/lib/libopencv_*.so) 和头文件 (/usr/local/include/opencv4/opencv2/*.h) 复制到 Petalinux 应用的根文件系统中。
在 Petalinux 工程的 project-spec/meta-user/recipes-apps/opencv_test 目录下,创建一个 files 目录,并将动态库和头文件复制到该目录下。同时,创建一个 opencv_test.bbappend 文件,用于指定如何将这些文件打包到根文件系统中。
修改 opencv_test.bbappend 文件
在 opencv_test.bbappend 文件中添加以下内容:
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI += " file://libopencv_core.so.4.1.0 \
file://libopencv_imgproc.so.4.1.0 \
file://libopencv_imgcodecs.so.4.1.0 \
file://libopencv_highgui.so.4.1.0 \
file://libopencv_videoio.so.4.1.0 \
file://cv.h \
file://opencv2.hpp \
"
S = "${WORKDIR}"
do_install_append() {
install -d ${D}${libdir}
install -m 0755 ${WORKDIR}/libopencv_core.so.4.1.0 ${D}${libdir}
install -m 0755 ${WORKDIR}/libopencv_imgproc.so.4.1.0 ${D}${libdir}
install -m 0755 ${WORKDIR}/libopencv_imgcodecs.so.4.1.0 ${D}${libdir}
install -m 0755 ${WORKDIR}/libopencv_highgui.so.4.1.0 ${D}${libdir}
install -m 0755 ${WORKDIR}/libopencv_videoio.so.4.1.0 ${D}${libdir}
install -d ${D}${includedir}/opencv4/opencv2
install -m 0644 ${WORKDIR}/cv.h ${D}${includedir}/opencv4/opencv2
install -m 0644 ${WORKDIR}/opencv2.hpp ${D}${includedir}/opencv4/opencv2
}
FILES_${PN} += "${libdir}/libopencv_core.so.4.1.0"
FILES_${PN} += "${libdir}/libopencv_imgproc.so.4.1.0"
FILES_${PN} += "${libdir}/libopencv_imgcodecs.so.4.1.0"
FILES_${PN} += "${libdir}/libopencv_highgui.so.4.1.0"
FILES_${PN} += "${libdir}/libopencv_videoio.so.4.1.0"
FILES_${PN} += "${includedir}/opencv4/opencv2/cv.h"
FILES_${PN} += "${includedir}/opencv4/opencv2/opencv2.hpp"
注意: 需要根据实际编译的 OpenCV 动态库名称修改 SRC_URI 和 do_install_append 中的文件名。${libdir} 和 ${includedir} 分别代表库文件和头文件的安装目录,通常分别为 /usr/lib 和 /usr/include。
修改应用源码
在应用源码中包含 OpenCV 头文件,并链接 OpenCV 动态库。需要在应用的 Makefile 中添加 -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lopencv_highgui -lopencv_videoio 链接选项。
编译 Petalinux 工程
使用 Petalinux 工具编译整个工程。
petalinux-build
打包和部署
编译完成后,将生成的镜像文件打包并部署到目标设备上。
petalinux-package --boot --fsbl images/linux/zynqmp_fsbl.elf --pmc images/linux/pmc_pmu_rom_release.elf --atf images/linux/bl31.elf --fpga images/linux/system.bit --kernel images/linux/Image --dtb images/linux/system.dtb
避坑经验总结
- 版本兼容性: 确保 OpenCV 版本与 Petalinux 版本兼容。不同版本的 Petalinux 可能需要不同版本的 OpenCV。
- 依赖库缺失: 在编译 OpenCV 之前,务必安装所有必要的依赖库。否则,编译过程可能会出错。
- 编译选项配置: 根据实际需求配置编译选项。关闭不必要的模块可以减少库的大小,并提高性能。
- 动态库链接: 在应用中使用 OpenCV 时,务必正确链接 OpenCV 动态库。否则,程序运行时可能会出现链接错误。
- 文件系统权限: 确保 OpenCV 动态库在目标文件系统上具有正确的权限。否则,程序运行时可能无法加载动态库。
ARM64 嵌入式设备上 OpenCV 性能优化
针对 ARM64 架构,可以考虑开启 NEON 指令集优化 OpenCV 性能。同时,根据实际应用场景选择合适的图像处理算法,避免使用过于复杂的算法。
在 Nginx 中,可以通过配置 worker 进程的数量和连接数,以及使用缓存等技术来优化性能。同样,在 OpenCV 中,也可以通过调整图像处理流程和算法来优化性能。例如,可以尝试使用多线程处理图像,或者使用更快的图像格式。
总之,在嵌入式系统中集成 OpenCV 需要充分考虑硬件资源和应用场景,并进行相应的优化。手动编译 OpenCV 可以更好地控制库的大小和功能,从而更好地满足嵌入式系统的需求。
冠军资讯
代码一只喵