在嵌入式 Linux 开发中,特别是使用 Xilinx Petalinux 构建的系统中,经常需要在 ARM64 架构上使用 OpenCV 进行图像处理。然而,Petalinux 默认提供的 OpenCV 版本可能较低,或者缺少某些必要的功能。因此,我们需要手动编译 OpenCV 4.1.0 源码,生成 ARM64 动态库 (.so),然后在 Petalinux 中进行打包和使用。本文将详细介绍这一过程,并分享一些实战中的避坑经验。
准备工作
- Petalinux 开发环境: 确保已搭建好 Petalinux 开发环境,包括 Petalinux 工具链和 SDK。并且需要配置好环境变量,例如
source /opt/petalinux/2019.1/settings.sh。 - OpenCV 4.1.0 源码: 从 OpenCV 官网下载 OpenCV 4.1.0 源码包 (opencv-4.1.0.zip)。
- 交叉编译工具链: 确认已安装并配置好 ARM64 的交叉编译工具链。Petalinux SDK 中自带,通常位于
/<petalinux_project>/components/yocto/sdk/sysroots/x86_64-petalinux-linux/usr/bin/aarch64-linux-gnu/。
编译 OpenCV 4.1.0
1. 解压源码
unzip opencv-4.1.0.zip
cd opencv-4.1.0
2. 创建构建目录
mkdir build
cd build
3. 配置 CMake
这是最关键的一步。需要根据 Petalinux 环境配置 CMake 参数,指定交叉编译工具链、安装路径等。
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/home/user/opencv_install \
-DCMAKE_TOOLCHAIN_FILE=../platforms/linux/arm64-gnu.toolchain.cmake \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_EXAMPLES=OFF \
-DWITH_CUDA=OFF \
-DWITH_OPENCL=OFF \
-DWITH_IPP=OFF \
-DENABLE_NEON=ON \
-DCMAKE_C_COMPILER=/opt/petalinux/2019.1/components/yocto/sdk/sysroots/x86_64-petalinux-linux/usr/bin/aarch64-linux-gnu/aarch64-linux-gnu-gcc \
-DCMAKE_CXX_COMPILER=/opt/petalinux/2019.1/components/yocto/sdk/sysroots/x86_64-petalinux-linux/usr/bin/aarch64-linux-gnu/aarch64-linux-gnu-g++ \
..
注意:
-DCMAKE_INSTALL_PREFIX指定了 OpenCV 的安装目录,后续打包需要用到。-DCMAKE_TOOLCHAIN_FILE可以使用 OpenCV 源码自带的 toolchain 文件,也可以手动创建一个,根据实际情况修改。-DBUILD_SHARED_LIBS=ON必须设置为 ON,才能生成动态库 (.so)。-DWITH_CUDA=OFF、-DWITH_OPENCL=OFF、-DWITH_IPP=OFF关闭不需要的模块,可以加快编译速度,并减小库的大小。嵌入式设备资源有限,尽量精简。-DENABLE_NEON=ON启用 NEON 指令集优化,可以提高 OpenCV 的性能。CMAKE_C_COMPILER和CMAKE_CXX_COMPILER指定了交叉编译器的路径,需要根据实际情况修改。
例如,手动创建 arm64-gnu.toolchain.cmake 文件内容如下:
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR aarch64)
SET(CMAKE_SYSROOT /opt/petalinux/2019.1/components/yocto/sdk/sysroots/cortexa72-cortexa53-xilinx-linux)
SET(CMAKE_STAGING_PREFIX /home/user/opencv_install)
SET(CMAKE_C_COMPILER /opt/petalinux/2019.1/components/yocto/sdk/sysroots/x86_64-petalinux-linux/usr/bin/aarch64-linux-gnu/aarch64-linux-gnu-gcc)
SET(CMAKE_CXX_COMPILER /opt/petalinux/2019.1/components/yocto/sdk/sysroots/x86_64-petalinux-linux/usr/bin/aarch64-linux-gnu/aarch64-linux-gnu-g++)
SET(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
4. 编译和安装
make -j4 # 使用 4 个线程进行编译,加快速度
sudo make install
编译完成后,OpenCV 动态库和头文件将被安装到 -DCMAKE_INSTALL_PREFIX 指定的目录中(这里是 /home/user/opencv_install)。
在 Petalinux 中打包使用
1. 创建 Petalinux 应用
使用 Petalinux 工具创建一个新的应用,例如 opencv_test。
petalinux-create -t apps --template c --name opencv_test --enable
cd opencv_test/src
2. 编写测试代码
编写一个简单的 OpenCV 测试代码,例如读取一张图片并显示出来。
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv ) {
if ( argc != 2 ) {
cout <<"usage: DisplayImage.out <Image_Path>" << endl;
return -1;
}
Mat image = imread( argv[1], IMREAD_COLOR ); // 读取图片
if ( !image.data ) {
cout << "No image data " << endl;
return -1;
}
namedWindow( "Display window", WINDOW_AUTOSIZE ); // 创建窗口
imshow( "Display window", image ); // 显示图片
waitKey(0); // 等待按键
return 0;
}
3. 修改 Makefile
修改 Makefile,添加 OpenCV 的头文件和库文件路径。
APP = opencv_test
SRCS = $(APP).c
CFLAGS = -Wall -O2
# 添加 OpenCV 头文件路径
CFLAGS += -I/home/user/opencv_install/include
CFLAGS += -I/home/user/opencv_install/include/opencv2
# 添加 OpenCV 库文件路径
LDFLAGS += -L/home/user/opencv_install/lib
# 添加 OpenCV 库
LDLIBS += -lopencv_core -lopencv_imgcodecs -lopencv_imgproc -lopencv_highgui
all: $(APP)
$(APP): $(SRCS)
$(CC) $(CFLAGS) -o $(APP) $(SRCS) $(LDFLAGS) $(LDLIBS)
clean:
rm -f $(APP) *.o
注意:
- 需要根据实际情况修改 OpenCV 的头文件和库文件路径。
-lopencv_core、-lopencv_imgcodecs、-lopencv_imgproc、-lopencv_highgui是 OpenCV 依赖的库,需要根据实际使用的模块添加。
4. 构建 Petalinux 系统
将编译好的 OpenCV 动态库 (.so) 文件拷贝到 Petalinux 系统中的 /lib 目录下,并将头文件拷贝到 /usr/include 目录下。也可以通过 Petalinux 的 petalinux-package 命令将 OpenCV 打包成一个 IPK 包,然后安装到系统中。这里演示直接拷贝的方式,方便快速验证。
在 Petalinux 工程目录下执行:
petalinux-build
petalinux-package --boot --fsbl images/linux/zynqmp_fsbl.elf --pmufw images/linux/pmufw.elf --atf images/linux/bl31.elf --fpga images/linux/system.bit
将生成的 image.ub 文件烧录到开发板上。
5. 运行测试程序
启动 Petalinux 系统后,将编译好的 opencv_test 可执行文件拷贝到开发板上,并运行。
./opencv_test /path/to/your/image.jpg
如果一切正常,应该能够看到图片显示在窗口中。如果出现错误,需要检查 OpenCV 的库文件是否正确安装,以及环境变量是否配置正确。
实战避坑经验总结
- 版本兼容性: 确保 OpenCV 版本与 Petalinux 系统中的其他库文件版本兼容。如果出现冲突,可能需要重新编译其他库文件。
- 编译参数: CMake 编译参数非常重要,需要根据实际情况进行配置。特别是交叉编译工具链的路径和安装路径,一定要正确指定。
- 依赖库: OpenCV 依赖很多第三方库,例如 libpng、libjpeg、libtiff 等。在编译 OpenCV 之前,需要确保这些库已经安装,并且版本符合要求。可以通过 Petalinux 的
petalinux-config -c rootfs命令来配置和安装这些库。 - 动态库链接: 在运行 OpenCV 程序时,需要确保动态库的链接路径正确。可以通过设置
LD_LIBRARY_PATH环境变量来指定动态库的路径。 - 内存管理: 在嵌入式系统中,内存资源有限。在使用 OpenCV 进行图像处理时,需要注意内存管理,避免内存泄漏。可以使用 OpenCV 提供的
Mat::release()函数来释放图像数据。 - 性能优化: 对于性能要求较高的应用,可以考虑使用 OpenCV 的 NEON 指令集优化,或者使用 OpenCL 进行 GPU 加速。同时,可以对图像处理算法进行优化,例如使用更高效的算法、减小图像尺寸等。
总结
本文详细介绍了如何在 Petalinux 中手动编译和使用 OpenCV 4.1.0 动态库。通过本文的介绍,相信大家能够掌握在 ARM64 架构下使用 OpenCV 的方法,并能够解决在实际开发中遇到的问题。希望本文能够帮助到大家!
冠军资讯
键盘上的咸鱼