资讯详情

资讯详情

RK3568 OpenCV4交叉编译实战:C++、Makefile、CMake与Qt四种方式

简介这份PDF文档是正点原子官方发布的《ATK-DLRK3568_OpenCV4使用手册》面向具备一定Linux基础、希望基于正点原子ATK-DLRK3568开发板开展计算机视觉开发的技术人员与嵌入式学习者。文档以Buildroot出厂系统为默认环境系统讲解OpenCV4在嵌入式平台上的完整开发流程涵盖交叉编译工具链安装、C与Python两种语言版本的OpenCV程序编写与编译方式并延伸至Makefile、CMakeLists及Qt项目中的集成方法附录还整理了常见问题解答便于读者快速排错。资源包共1个PDF文件大小约1.41MB内容紧凑、结构清晰适合按章节逐步实践。目前已有119人学习读者可借助该手册掌握在四核A552.0GHz主频开发板上运行OpenCV程序的完整链路从环境配置到多语言工程落地均有覆盖是嵌入式视觉入门与工程实践的实用参考。1. 拿到 RK3568 的 OpenCV4 手册先别急着敲代码很多人拿到 ATK-DLRK3568 这块板子第一反应是跑个摄像头 demo 看看效果结果卡在第一步宿主机上g opencv_test.cpp一敲报错找不到opencv2/opencv.hpp。这不是代码写错了是编译环境根本没配对。这块板子四核 A552.0GHz跑日常视觉应用绰绰有余出厂 Buildroot 系统里已经预置了 OpenCV 4.5.5库文件躺在/usr/lib下连 freetype 字体渲染引擎都带上了。问题从来不在板子端而在你怎么把宿主机上写的程序编译成能在 aarch64 上跑的二进制。这份手册解决的就是这个断层从交叉编译工具链安装到 C 命令行、Makefile、CMakeLists、Qt 四种编译方式再到 Python 脚本直接扔板子上跑最后附了常见问题。适合有 Linux 基础、想在嵌入式端做计算机视觉的开发者。如果你之前只在 x86 上玩过 OpenCV或者用树莓派跑过 Python 版那这份东西能帮你把「交叉编译」这个黑匣子拆开。下面按我实际复现的顺序把每一步的参数和坑说清楚。2. 交叉编译工具链装在哪、怎么装、为什么不能乱改路径2.1 工具链的来源与安装路径选择正点原子这个工具链是从 RK3568 的 SDK 里用 Buildroot 生成后打包出来的好处是你不用自己编译整个 SDK 就能拿到aarch64-buildroot-linux-gnu-g。文件名叫atk-dlrk3568-toolchain-arm-buildroot-linux-gnueabihf-x86_64-(版本号).run在光盘资料的05、开发工具/01、交叉编译工具目录下。用 WinScp 或者 scp 传到 Ubuntu 20.04 上先给执行权限chmod 777 atk-dlrk3568-toolchain-arm-buildroot-linux-gnueabihf-x86_64.run然后执行安装./atk-dlrk3568-toolchain-arm-buildroot-linux-gnueabihf-x86_64.run安装脚本会问你安装路径默认是/opt/atk-dlrk3568-toolchain。这里有个血泪经验不要改这个路径。手册里后面所有的编译命令、Makefile、CMakeLists 都硬编码了这个路径你一改后面每个文件都得跟着改漏一个就报找不到编译器。输入y确认等 1 到 2 分钟取决于你硬盘速度。装完之后验证一下/opt/atk-dlrk3568-toolchain/bin/aarch64-buildroot-linux-gnu-g --version能输出版本信息就说明工具链就位了。注意手册里有时候写atk-dlrk356x-toolchain有时候写atk-dlrk3568-toolchain这是文档笔误实际安装出来是atk-dlrk3568-toolchain你以实际目录为准。如果你之前装过这个工具链这一步跳过别重复装。2.2 工具链目录结构与你需要关心的三个路径装完之后别急着写代码先花两分钟把目录结构看清楚后面所有编译参数都从这里来。工具链根目录下有三个关键位置路径用途/opt/atk-dlrk3568-toolchain/bin/编译器可执行文件如aarch64-buildroot-linux-gnu-g/opt/atk-dlrk3568-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/include/头文件根目录OpenCV 头文件在opencv4子目录下/opt/atk-dlrk3568-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/lib/库文件目录-l参数链接的库都在这里sysroot这个概念是关键它模拟了目标板上的根文件系统结构编译器从这里找头文件和库而不是从你宿主机的/usr/include找。所以-I和-L必须指向 sysroot 下的路径不能指向宿主机的 OpenCV。很多人编译报错undefined reference to cv::imread就是因为链接器跑到宿主机库目录去找了版本对不上。3. C 程序四种编译方式从命令行到 Qt 的完整复现3.1 命令行直接编译最原始但最能看清参数先写一个最简单的测试程序opencv_test.cpp#include opencv4/opencv2/opencv.hpp #include iostream int main() { // 读取开发板上的图片路径按实际替换 cv::Mat image cv::imread(/opt/apps/src/logo/alientek_logo.png); if (image.empty()) { std::cout 无法读取图片文件 std::endl; return -1; } // 创建窗口并显示 cv::namedWindow(Image, cv::WINDOW_AUTOSIZE); cv::imshow(Image, image); // 等待按键0 表示无限等待 cv::waitKey(0); cv::destroyAllWindows(); return 0; }注意头文件路径是opencv4/opencv2/opencv.hpp不是opencv2/opencv.hpp。因为 sysroot 下头文件装在opencv4子目录里你写-I .../include/opencv4之后理论上可以写opencv2/opencv.hpp但手册里统一用了带opencv4前缀的写法你跟着写不会错。编译命令是一整行用\换行/opt/atk-dlrk3568-toolchain/bin/aarch64-buildroot-linux-gnu-g opencv_test.cpp -o opencv_test \ -I /opt/atk-dlrk3568-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/include/opencv4 \ -L /opt/atk-dlrk3568-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/lib \ -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_videoio -lopencv_imgcodecs逐段拆解-o opencv_test指定输出文件名-I告诉编译器去哪找头文件-L告诉链接器去哪找库文件-l后面跟库名链接器会自动补lib前缀和.so后缀。这里链接了五个库core是核心数据结构highgui负责窗口显示imgproc是图像处理videoio管视频输入输出imgcodecs管图片编解码。你用了哪个模块就链哪个多链不报错但没必要。编译完把opencv_test拷到板子上。传输方式用 scp 或者 adb 都行手册里推荐参考辅助文档。板子上执行./opencv_test屏幕上应该显示一张 logo 图可以全屏放大。如果报error while loading shared libraries: libopencv_core.so.4.5: cannot open shared object file说明板子上的库路径没配好检查/usr/lib下有没有对应的.so文件。3.2 Makefile 版本把参数固化下来命令行编译每次敲一长串太累Makefile 就是把那些参数写死。在源码目录创建MakefileTOOLCHAIN_DIR : /opt/atk-dlrk3568-toolchain G : ${TOOLCHAIN_DIR}/bin/aarch64-buildroot-linux-gnu-g SYSROOT : ${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu/sysroot/usr/include CMAKE_SYSROOT : ${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu/sysroot CFLAGS -I${SYSROOT} -I${SYSROOT}/opencv4 CFLAGS --sysroot${CMAKE_SYSROOT} LD_FLAGS : -lopencv_core -lopencv_videoio -lopencv_video \ -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc all: $(G) opencv_test.cpp $(CFLAGS) $(LD_FLAGS) -o opencv_test echo Build Done ... clean: rm opencv_test这里比命令行多了一个--sysroot${CMAKE_SYSROOT}参数。这个参数的作用是告诉编译器所有绝对路径的头文件和库都相对于这个 sysroot 来找。有了它-I和-L可以写得更简洁但手册里还是显式写了完整路径你照抄就行。make编译make clean清理。生成的二进制同样拷到板子上跑。3.3 CMakeLists 版本工程化项目的选择CMake 的好处是跨平台、易维护大型项目基本都用它。创建CMakeLists.txtcmake_minimum_required(VERSION 3.8) project(opencv_test) set(TOOLCHAIN_DIR /opt/atk-dlrk3568-toolchain) set(CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/bin/aarch64-buildroot-linux-gnu-g) set(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/bin/aarch64-buildroot-linux-gnu-gcc) set(SYSROOT ${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu/sysroot/usr/include) set(CMAKE_SYSROOT ${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu/sysroot) set(CMAKE_CXX_STANDARD 11) set(OPENCV_LIBS opencv_core opencv_videoio opencv_video opencv_highgui opencv_imgcodecs opencv_imgproc) include_directories(${SYSROOT}) include_directories(${SYSROOT}/opencv4) add_executable(opencv_test opencv_test.cpp) target_link_libraries(opencv_test ${OPENCV_LIBS})关键点是set(CMAKE_CXX_COMPILER ...)直接指定交叉编译器而不是用toolchain file的方式。这样写简单直接适合单一目标平台的项目。构建步骤mkdir build cd build cmake .. makecmake ..会根据上一级目录的CMakeLists.txt生成 Makefile然后make编译。生成的二进制在build目录下。make clean清理。注意如果你之前在同一目录跑过 Makefile 版本先make clean再建build目录否则 CMake 生成的 Makefile 会覆盖掉原来的。3.4 Qt 版本用 pkgconfig 自动找库Qt 项目里集成 OpenCV 最简单的方式是用pkgconfig。在.pro文件里加两行CONFIG link_pkgconfig PKGCONFIG opencv4Qt 会自动根据opencv4.pc文件找到头文件和库路径不用你手动指定-I和-L。前提是你的交叉编译环境里pkgconfig能找到opencv4.pc这个文件在 sysroot 的usr/lib/pkgconfig目录下。然后在代码里正常#include opencv4/opencv2/opencv.hpp就行。手册里给的测试代码只是在构造函数里imread了一张图没做显示主要是验证链接是否通过。CtrlB构建如果 Qt Creator 的构建套件选的是 ATK-DLRK3568 的交叉编译器就能编译出 aarch64 的二进制。4. Python 版本与避坑排查为什么你的程序跑不起来4.1 Python 脚本直接跑不需要交叉编译Python 版本简单得多因为不需要编译。板子出厂系统里已经装了 Python3 和 OpenCV 的 Python 绑定。写一个opencv_test.pyimport cv2 def main(): # 读取图片路径按实际替换 image cv2.imread(/opt/apps/src/logo/alientek_logo.png) if image is None: print(无法读取图片文件) return # WINDOW_NORMAL 允许调整窗口大小 cv2.namedWindow(Image, cv2.WINDOW_NORMAL) cv2.imshow(Image, image) # 等待按键0 表示无限等待 cv2.waitKey(0) cv2.destroyAllWindows() if __name__ __main__: main()把文件拷到板子上直接python3 opencv_test.py。注意cv2.waitKey(0)在无桌面的终端环境下可能没反应因为需要 GUI 支持。Buildroot 系统里如果有 Weston 桌面就能正常弹窗。如果没有屏幕用 HDMI 显示器Weston 桌面可能只显示在中间手册附录里给了解决方案参考 RK 官方文档把 HDMI 旋转 90 度或设为主屏。4.2 避坑排查五个我实际踩过的坑现象一编译时报fatal error: opencv2/opencv.hpp: No such file or directory。原因-I路径没指对或者头文件路径写成了宿主机路径。解决确认-I指向的是 sysroot 下的usr/include/opencv4不是宿主机的/usr/include/opencv4。用ls命令确认那个目录下确实有opencv2文件夹。现象二链接时报undefined reference to cv::imshow。原因-l参数漏了opencv_highgui或者库路径-L指错了。解决检查-L是否指向 sysroot 的usr/lib检查-l列表里有没有包含你用到的模块。imshow在highgui里imread在imgcodecs里Mat在core里。现象三板子上运行报error while loading shared libraries。原因板子上的LD_LIBRARY_PATH没包含 OpenCV 库路径或者库文件被删了。解决export LD_LIBRARY_PATH/usr/lib:$LD_LIBRARY_PATH或者确认/usr/lib下有libopencv_core.so.4.5等文件。出厂系统默认是有的如果你自己刷了其他系统可能没带 OpenCV。现象四Qt 项目编译通过但运行时报GLIBCXX_3.4.29 not found。原因宿主机 Qt Creator 用的编译器版本和板子上的 libstdc 版本不匹配。解决确保 Qt 构建套件里的编译器就是/opt/atk-dlrk3568-toolchain/bin/aarch64-buildroot-linux-gnu-g不要用系统自带的 g。现象五Python 脚本报ModuleNotFoundError: No module named cv2。原因板子上的 Python 环境没有 OpenCV 绑定或者你用的 Python 版本不对。解决确认板子上python3 -c import cv2; print(cv2.__version__)能输出版本号。如果不行说明出厂系统里没装 Python 版 OpenCV需要自己交叉编译 Python 绑定那就麻烦多了建议直接用 C 版本。5. 进阶技巧用 pkgconfig 简化编译参数与验证方法命令行编译那一长串-I和-L参数写一次两次还行项目大了容易漏。其实 sysroot 里带了pkgconfig文件可以用pkg-config自动生成编译参数。先设置环境变量export PKG_CONFIG_PATH/opt/atk-dlrk3568-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/lib/pkgconfig export PKG_CONFIG_SYSROOT_DIR/opt/atk-dlrk3568-toolchain/aarch64-buildroot-linux-gnu/sysroot然后查一下 OpenCV 的编译参数pkg-config --cflags --libs opencv4输出应该是一串-I和-l参数。你可以直接在编译命令里用$(pkg-config --cflags --libs opencv4)替换手动写的那些。这样换工具链路径或者换 OpenCV 版本时只需要改PKG_CONFIG_PATH不用改 Makefile。验证编译出来的二进制是不是 aarch64 架构用file命令file opencv_test输出里应该包含ELF 64-bit LSB executable, ARM aarch64。如果是x86-64说明你用了宿主机的编译器链接的也是宿主机的库拷到板子上肯定跑不起来。这个检查我每次编译完都会做一遍比拷到板子上再报错省时间。还有一个技巧如果板子上没有屏幕可以用cv::imwrite把处理结果保存成图片然后用 scp 拉回宿主机看。这样不需要 GUI 支持适合纯命令行环境调试算法。把imshow换成imwritecv::imwrite(/tmp/output.png, image);然后在板子上执行完把/tmp/output.png拷回来。这个习惯帮我省了很多来回插拔 HDMI 线的时间。从那以后我每次交叉编译完都强制走一遍file检查加imwrite验证确认二进制架构对了、算法逻辑也对了再上板子跑 GUI。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →