[RK3588/RK3568] 嵌入式视觉应用开发:OpenCV3.4.3与FFmpeg4.2.9交叉编译实战指南

📅 发布时间:2026/7/11 12:22:39 👁️ 浏览次数:
[RK3588/RK3568] 嵌入式视觉应用开发:OpenCV3.4.3与FFmpeg4.2.9交叉编译实战指南
1. 环境准备搭建你的交叉编译“厨房”如果你玩过嵌入式开发肯定知道一个让人头疼的事儿在电脑上跑得好好的程序一放到开发板上就各种报错最常见的就是“找不到库”或者“指令集不兼容”。这背后的核心原因就是你的电脑通常是x86_64架构和开发板比如RK3568/RK3588的ARM64架构是两种完全不同的“语言体系”。交叉编译就是解决这个问题的“翻译官”和“厨师”。它让你能在强大的电脑上用专门的工具为开发板“烹饪”出可以直接运行的软件和库。所以在开始动手编译OpenCV和FFmpeg之前我们得先把“厨房”——也就是交叉编译环境——给搭好。这个环境主要包含两部分一个干净的Linux系统我们选Ubuntu和一套针对ARM64架构的交叉编译工具链。我强烈建议你使用虚拟机来安装Ubuntu这样能保证环境纯净避免和你电脑上已有的各种库产生冲突。版本上Ubuntu 18.04或20.04 LTS都是经过大量验证的稳定选择社区资源也丰富遇到问题容易搜到答案。我这里以Ubuntu 18.04为例。装好系统后第一件事是更新软件源并安装一些基础编译工具打开终端一口气执行下面这些命令sudo apt-get update sudo apt-get upgrade -y sudo apt-get install -y build-essential cmake git wget unzip pkg-config这几行命令的作用是update刷新软件仓库列表upgrade升级已安装的包然后安装编译所需的“全家桶”。build-essential包含了gcc, g, make等核心工具cmake是OpenCV编译的配置工具git,wget,unzip用于下载和解压源码pkg-config在后面配置库依赖时会用到。接下来是最关键的一步获取交叉编译工具链。你可以把它理解为一套专门为ARM64架构定制的“厨具”。瑞芯微官方通常会提供优化过的工具链你也可以使用通用的Linaro或ARM官方工具链。为了通用性我们采用Linaro GCC 6.3.1版本这个版本与RK3568/RK3588的Cortex-A系列内核兼容性很好。我们通过wget下载并解压它到/usr/local/arm64目录这个路径你可以自定义但后续所有命令都要对应修改sudo mkdir -p /usr/local/arm64 cd /usr/local/arm64 sudo wget https://releases.linaro.org/components/toolchain/binaries/6.3-2017.05/aarch64-linux-gnu/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu.tar.xz sudo tar -xf gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu.tar.xz解压后你会看到一个长长的目录名。为了方便我们可以给它创建一个软链接或者直接把它的bin目录路径添加到系统的环境变量PATH里。我更喜欢直接添加环境变量的方式因为更清晰。注意这个环境变量设置是“临时”的只对当前终端窗口有效。所以我强烈建议你从这一步开始后续所有操作都在同一个终端窗口里完成不要关闭它否则需要重新设置。export PATH/usr/local/arm64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin:$PATH设置完后验证一下工具链是否生效aarch64-linux-gnu-gcc -v如果终端打印出了gcc的版本信息比如gcc version 6.3.1 20170404并且前缀是aarch64-linux-gnu-那么恭喜你“厨房”已经准备就绪我们可以开始准备“食材”——源码了。2. 获取与处理源码挑选稳定的“食材”编译就像做菜食材源码的新鲜度和质量直接决定最终成品的稳定性。对于嵌入式开发我个人的经验是不求最新但求最稳。最新的版本可能包含未经验证的新特性或兼容性问题在资源受限的嵌入式平台上容易翻车。因此我们选择经过长期考验的经典版本OpenCV 3.4.3 和 FFmpeg 4.2.9。这两个版本在功能、稳定性和社区支持上达到了一个很好的平衡足以满足绝大多数图像和视频处理的基础需求。首先我们在家目录下创建一个专门的工作目录让一切井井有条cd ~ mkdir -p workspace/opencv_ffmpeg_build cd workspace/opencv_ffmpeg_build这个opencv_ffmpeg_build目录将是我们所有编译操作的大本营。接下来分别下载两个源码包。对于OpenCV我们从GitHub的Release页面下载wget -O opencv-3.4.3.zip https://github.com/opencv/opencv/archive/3.4.3.zip unzip opencv-3.4.3.zip对于FFmpeg从其官方镜像站下载wget http://ffmpeg.org/releases/ffmpeg-4.2.9.tar.gz tar -zxvf ffmpeg-4.2.9.tar.gz解压后你会看到opencv-3.4.3和ffmpeg-4.2.9两个文件夹。这里有一个小细节FFmpeg的编译我们会先进行并且将其安装到一个独立的目录中。然后在编译OpenCV时通过配置选项告诉它“FFmpeg库在那边请链接它。”这样做的好处是依赖关系清晰也方便单独管理每个库。所以我们再创建两个子目录一个用于FFmpeg的编译过程ffmpeg_build一个用于存放最终的安装结果arm64_installmkdir ffmpeg_build arm64_install现在食材已经备好并且分门别类放好了。接下来我们要开始处理第一道主菜FFmpeg。为什么先编译FFmpeg因为OpenCV的某些功能特别是视频读写可以依赖FFmpeg先编译好FFmpeg就能让OpenCV在配置阶段发现并链接它从而启用这些功能。3. 交叉编译FFmpeg为视频处理打好地基FFmpeg是处理视频和音频的“瑞士军刀”我们的目标是在开发板上实现MP4H.264编码视频的解码播放。交叉编译FFmpeg相对直接但配置参数是关键它决定了最终库包含哪些功能体积多大。对于嵌入式设备我们必须做减法只编译我们需要的部分以节省宝贵的存储空间和内存。进入FFmpeg源码目录并开始配置。这里我详细解释一下每个重要参数的含义你以后可以根据自己的需求调整cd ffmpeg-4.2.9 ./configure \ --enable-cross-compile \ # 启用交叉编译 --prefix$HOME/workspace/opencv_ffmpeg_build/arm64_install \ # 安装路径 --cross-prefixaarch64-linux-gnu- \ # 交叉工具链前缀 --archaarch64 \ # 目标架构 --target-oslinux \ # 目标系统 --enable-gpl \ # 启用GPL许可代码某些解码器需要 --extra-cflags-fPIC -O2 \ # 编译标志位置无关代码 优化级别2 --extra-ldflags-Wl,-rpath-link,$HOME/workspace/opencv_ffmpeg_build/arm64_install/lib \ # 链接器标志帮助找库 --disable-static \ # 禁止生成静态库减小体积 --enable-shared \ # 启用生成动态库.so文件 --disable-programs \ # 不编译ffmpeg, ffplay等命令行程序我们只要库 --disable-doc \ # 不编译文档 --disable-avdevice \ # 禁用设备相关模块如摄像头采集开发板可能不需要 --disable-swresample --disable-avfilter --disable-postproc --disable-network \ # 禁用更多非核心模块 --enable-decoderh264 --enable-parserh264 --enable-demuxerh264 \ # 仅启用H.264解码相关 --disable-encoders --disable-muxers --disable-protocols \ # 禁用所有编码、封装和协议 --disable-filters \ # 禁用滤镜 --disable-asm \ # 禁用汇编优化避免兼容性问题 --disable-yasm # 禁用yasm汇编器简化环境参数解读与避坑指南--prefix这个路径非常重要它指定了make install后所有编译好的库文件和头文件安装到哪里。我们统一安装到之前创建的arm64_install目录方便后续打包。--cross-prefix告诉配置脚本我们的编译工具如gcc全名是aarch64-linux-gnu-gcc它会在所有工具名前加上这个前缀去寻找。--extra-cflags-fPIC生成位置无关代码这是编译动态库的常见要求能确保库被加载到内存的任何地址都能运行。--disable-static --enable-shared嵌入式环境通常使用动态库可以多个程序共享节省空间。静态库虽然部署简单但体积巨大。--disable-programs这个很重要我们只需要FFmpeg的库libavcodec, libavformat等不需要它的可执行工具。禁用它们能显著减少编译时间和最终体积。最后的--enable-decoderh264...和一系列--disable这是嵌入式编译的精髓——功能裁剪。我们只明确启用MP4/H.264解码这条链路所需的最少组件其他一切如编码器、网络流、复杂滤镜全部关闭。这能极大减小库文件大小我实测下来这样编译出的FFmpeg核心库体积能减少70%以上。配置命令执行后如果看到License: GPL version 3 or later等摘要信息并且没有报错就可以开始编译了make -j$(nproc) # 使用所有CPU核心并行编译加快速度 make installmake -j$(nproc)中的$(nproc)会自动获取你电脑的CPU核心数进行并行编译。编译完成后去arm64_install目录看看应该已经有了include头文件和lib库文件子目录。这就是我们为ARM64平台“烹饪”好的FFmpeg库。4. 交叉编译OpenCV配置是成功的关键有了FFmpeg作为基础现在可以编译主角OpenCV了。OpenCV的编译通过CMake来配置它的参数更多更复杂但正是这些参数给了我们极大的灵活性。我们的目标是一个支持基本图像读写JPEG, PNG, TIFF和视频解码通过FFmpeg的、精简的OpenCV库。首先回到我们的工作目录并进入OpenCV源码文件夹创建一个专门用于本次编译的构建目录cd ~/workspace/opencv_ffmpeg_build/opencv-3.4.3 mkdir build_arm64 cd build_arm64接下来是最关键的CMake配置步骤。在运行cmake命令前必须确保之前设置的交叉编译工具链环境变量PATH依然有效并且要设置一个关键的环境变量PKG_CONFIG_PATH让CMake能自动找到我们刚刚编译好的FFmpeg库。export PKG_CONFIG_PATH$HOME/workspace/opencv_ffmpeg_build/arm64_install/lib/pkgconfig:$PKG_CONFIG_PATH现在执行CMake命令。这是一条很长的命令我把它分成功能块来讲解cmake -D CMAKE_BUILD_TYPERELEASE \ # 发布模式优化性能 -D CMAKE_INSTALL_PREFIX$HOME/workspace/opencv_ffmpeg_build/arm64_install \ # 安装路径和FFmpeg放一起 -D CMAKE_C_COMPILERaarch64-linux-gnu-gcc \ # 指定C交叉编译器 -D CMAKE_CXX_COMPILERaarch64-linux-gnu-g \# 指定C交叉编译器 # 编译与链接标志 -D BUILD_SHARED_LIBSON \ # 构建动态库 -D CMAKE_CXX_FLAGS-fPIC -O2 \ -D CMAKE_C_FLAGS-fPIC -O2 \ -D CMAKE_EXE_LINKER_FLAGS-Wl,-rpath-link,$HOME/workspace/opencv_ffmpeg_build/arm64_install/lib -lpthread -ldl \ # 关键功能开关启用FFmpeg禁用GUI和高阶功能 -D WITH_FFMPEGON \ # 启用FFmpeg支持关键 -D WITH_GSTREAMEROFF \ # 禁用GStreamer简化 -D WITH_GTKOFF -D WITH_QTOFF \ # 禁用图形界面支持嵌入式通常无桌面 -D WITH_OPENGLOFF -D WITH_VULKANOFF \ # 禁用图形API -D WITH_CUDAOFF -D WITH_OPENCLOFF \ # 禁用GPU计算RK3588的NPU需另配 # 图像编解码器支持按需开启 -D WITH_JPEGON \ # 启用JPEG支持 -D WITH_PNGON \ # 启用PNG支持 -D WITH_TIFFON \ # 启用TIFF支持 -D WITH_WEBPON \ # 启用WebP支持 -D WITH_JASPEROFF \ # 通常禁用JPEG2000专利问题 -D WITH_OPENEXROFF \ # 禁用高动态范围图像格式复杂 # 优化与裁剪关闭非必要模块 -D BUILD_opencv_javaOFF -D BUILD_opencv_pythonOFF -D BUILD_opencv_jsOFF \ # 不绑定额外语言 -D BUILD_EXAMPLESOFF -D BUILD_TESTSOFF \ # 不编译示例和测试节省时间 -D BUILD_PERF_TESTSOFF \ -D BUILD_DOCSOFF \ -D BUILD_opencv_appsOFF \ # 指定FFmpeg路径如果pkg-config没找到可显式指定 -D FFMPEG_INCLUDE_DIR$HOME/workspace/opencv_ffmpeg_build/arm64_install/include \ -D FFMPEG_LIB_DIR$HOME/workspace/opencv_ffmpeg_build/arm64_install/lib \ ..配置详解与常见问题CMAKE_C_COMPILER和CMAKE_CXX_COMPILER这是告诉CMake使用交叉编译器的最核心参数。WITH_FFMPEGON这个选项必须打开OpenCV才会去链接FFmpeg来实现视频读写。CMake会通过我们设置的PKG_CONFIG_PATH去查找FFmpeg。如果配置日志里显示FFMPEG: YES并且列出了libavcodec, libavformat等就说明找到了。图形界面相关GTK, QT, OpenGL务必全部关闭。这些库在ARM开发板的精简系统上通常不存在如果开启编译时会报错找不到头文件或库。图像编解码器根据你的实际需要选择。JPEG和PNG是最常用的建议开启。TIFF和WebP看项目需求。最后的..表示CMakeLists.txt文件在上一级目录。执行完CMake后仔细查看终端输出。重点关注FFMPEG、JPEG、PNG等条目是否为YES以及Compiler一栏是否显示为aarch64-linux-gnu-g。确认无误后开始编译和安装make -j$(nproc) make install这个过程会比较漫长取决于你的电脑性能。编译成功后再次查看arm64_install目录你会发现里面除了FFmpeg的文件新增了大量OpenCV的库如libopencv_core.so.3.4libopencv_highgui.so.3.4等和头文件。至此两大核心库都已“烹饪”完成。5. 部署与测试在开发板上验证成果编译完成只是成功了一半把库正确部署到开发板上并跑通测试程序才是最终的胜利。首先我们需要将arm64_install这个“成果包”整理好。为了方便传输可以把它打包cd ~/workspace/opencv_ffmpeg_build tar -zcvf arm64_opencv_ffmpeg.tar.gz arm64_install/得到一个arm64_opencv_ffmpeg.tar.gz压缩包。通过SCP、U盘或者SD卡等方式将它拷贝到你的RK3568或RK3588开发板上。假设你在开发板上的用户目录是/home/rock并且已经解压到了该目录。部署的核心是将动态库文件放到系统能够找到的地方。有两种常见方法拷贝到系统库目录如/usr/lib或/lib/aarch64-linux-gnu。这需要root权限并且可能会覆盖系统原有库不太推荐。设置运行时链接路径这是更灵活和安全的方式。将库文件放在自定义目录如/home/rock/arm64_install/lib然后通过环境变量LD_LIBRARY_PATH告诉系统去那里找。在开发板的终端里执行export LD_LIBRARY_PATH/home/rock/arm64_install/lib:$LD_LIBRARY_PATH为了让这个设置在每次登录时生效可以把这行命令添加到开发板用户的~/.bashrc文件末尾。现在我们来写一个简单的C测试程序验证OpenCV和FFmpeg是否正常工作。在开发板上创建一个test_opencv.cpp文件#include opencv2/opencv.hpp #include iostream int main() { // 测试1读取一张图片 cv::Mat image cv::imread(test.jpg); if(image.empty()) { std::cout 错误无法加载图片 test.jpg std::endl; return -1; } std::cout 图片加载成功尺寸: image.cols x image.rows std::endl; // 测试2读取视频文件验证FFmpeg集成 cv::VideoCapture cap(test.mp4); if(!cap.isOpened()) { std::cout 错误无法打开视频 test.mp4 std::endl; return -1; } std::cout 视频打开成功开始解码帧... std::endl; cv::Mat frame; int frame_count 0; while(cap.read(frame) frame_count 10) { // 只读前10帧 frame_count; } cap.release(); std::cout 成功解码 frame_count 帧视频。 std::endl; std::cout 所有测试通过OpenCV与FFmpeg交叉编译库工作正常。 std::endl; return 0; }编译这个测试程序。注意编译时也需要指定头文件和库文件的路径aarch64-linux-gnu-g test_opencv.cpp -o test_opencv \ -I /home/rock/arm64_install/include/opencv2 \ -I /home/rock/arm64_install/include \ -L /home/rock/arm64_install/lib \ -lopencv_core -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs编译成功后生成test_opencv可执行文件。确保当前目录下有test.jpg图片和test.mp4H.264编码视频文件然后运行./test_opencv如果看到“图片加载成功”和“成功解码X帧视频”的输出那么恭喜你整个交叉编译、部署和运行的流程已经完全走通你已经在RK3568/RK3588开发板上成功搭建了一个功能完备的嵌入式视觉处理基础环境。这个环境可以作为你后续开发人脸识别、物体检测、视频分析等更复杂应用的坚实跳板。在实际项目中你可能还需要根据需求调整编译选项例如开启NEON指令集优化以获得更好的性能或者链接TensorFlow Lite等推理框架来部署AI模型但万变不离其宗核心的交叉编译方法论和流程已经在你手中了。