ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

树莓派4B上部署Halcon:ARM平台机器视觉实战指南

树莓派4B上部署Halcon:ARM平台机器视觉实战指南 1. 为什么要在树莓派4B上折腾Halcon1.1 一个不太常规但很实用的组合把Halcon跑在树莓派4B上这个想法我第一次跟同行提的时候对方愣了两秒然后问我是不是闲得慌。说实话一开始确实有点折腾的成分但真正做下来之后我发现这个组合在特定场景下非常香。Halcon是机器视觉领域的老牌商业算法库算子丰富、稳定性好、精度高在工业检测、测量、定位、缺陷检测这些场景里几乎是标杆级的存在。但它传统上跑在x86工控机加Windows的平台上整套方案的成本不低。而树莓派4B作为ARM平台的代表四核Cortex-A72、最高8GB内存、价格几百块功耗低、体积小、接口丰富天生适合做嵌入式视觉终端。把这两者结合起来核心诉求其实很明确在低成本、低功耗的嵌入式设备上跑通工业级的视觉算法。比如产线上的小型检测工位、移动机器人上的视觉模块、教学实验平台、创客项目里的高精度识别需求这些场景用一台工控机属于杀鸡用牛刀用OpenCV又可能在某些算法精度和稳定性上不够看Halcon加树莓派就是一个折中的甜点区。当然这条路不是官方主推的路线坑不少。Halcon官方对ARM平台的支持主要集中在NVIDIA Jetson系列和部分ARMv8开发板上树莓派4B虽然也是ARMv8Cortex-A7264位但官方并没有专门为树莓派做适配包。所以整个部署过程需要我们自己动手选系统、装依赖、处理license、配CMake、调运行时环境。这篇文章就是把我踩过的坑和最终跑通的方案完整记录下来给同样有这个需求的同行省点时间。适合读这篇的人有一定Linux基础、了解机器视觉基本概念、手头有树莓派4B、想在上面跑Halcon做算法验证或产品原型的开发者。如果你完全没接触过交叉编译和CMake建议先补一下基础再来不然中间某些步骤会卡得比较难受。1.2 先想清楚你到底需不需要这么做在动手之前我建议你先问自己一个问题你的算法真的需要Halcon吗如果你的需求只是简单的图像读取、滤波、边缘检测、模板匹配OpenCV在树莓派上跑得好好的社区支持也完善没必要折腾Halcon。但如果你需要的是亚像素级测量、形状匹配的鲁棒性、复杂的标定流程、3D点云处理比如深度图转点云、或者你已有的算法资产就是基于Halcon开发的那把它搬到树莓派上就有实际价值。另外一个现实考量是license。Halcon是商业软件树莓派上跑需要有效的license文件。如果你手头有正版授权比如USB加密狗或者软授权那没问题如果没有这个方案在产品化时会有法律风险。教学和评估用途通常有对应的授权方式具体要看你所在机构的协议。我自己的场景是做一个移动检测平台需要在设备端完成实时测量同时算法逻辑已经在Halcon上验证过了不想重写。所以选择了这条路。下面进入正题。2. 系统选型与环境准备2.1 操作系统的选择Ubuntu 20.04还是22.04树莓派4B能跑的系统不少Raspberry Pi OS、Ubuntu Server、Ubuntu Desktop、甚至一些轻量级发行版。但考虑到Halcon对glibc版本、依赖库的要求我强烈建议用Ubuntu 20.04 LTS64位。原因有几个。第一Halcon的Linux版本对glibc有最低版本要求20.04的glibc 2.31能满足大部分较新版本Halcon的需求而Raspberry Pi OS基于Debianglibc版本可能偏低或者依赖包命名不一致容易出问题。第二Ubuntu 20.04的ARM64生态成熟各种依赖库apt直接装省去大量编译时间。第三22.04虽然更新但部分Halcon版本对它的测试覆盖不如20.04我实测在22.04上遇到过libssl版本冲突的问题虽然能解决但多花时间。安装系统这一步不展开用Raspberry Pi Imager写卡就行。注意选Ubuntu Server 20.04.5 LTS (64-bit)不要选Desktop版桌面环境会吃掉大量内存和CPU对视觉算法没帮助。装完之后先做基础配置# 更新系统 sudo apt update sudo apt upgrade -y # 安装基础工具 sudo apt install -y build-essential cmake git wget curl unzip # 确认架构 uname -m # 应该输出 aarch64注意一定要确认是aarch64而不是armv7l。如果你装成了32位系统后面Halcon的64位库根本加载不了白忙一场。2.2 内存与存储的现实考量树莓派4B有2GB、4GB、8GB几个版本。跑Halcon做视觉处理我建议至少4GB最好8GB。Halcon的算子很多是内存密集型的特别是形状匹配和3D处理2GB版本跑小图还行一旦图像分辨率上到500万像素以上或者做多模板匹配内存直接爆。存储方面用高速microSD卡A2级别或者SSD通过USB 3.0转接。Halcon的库文件和license加起来几百MB加上系统本身16GB卡勉强够32GB比较舒服。如果做大量图像缓存建议上SSD读写速度对整体流程影响很大。还有一个容易被忽略的点散热。树莓派4B满载跑视觉算法时CPU温度很容易上80度触发降频后性能断崖式下跌。加个散热风扇或者金属散热壳这是必须的。我实测加风扇前后同一个模板匹配任务耗时差了将近40%。2.3 Halcon版本的选择与获取Halcon版本迭代很快从18.11到20.11、21.11、22.11、23.11每个版本对ARM的支持程度不同。我推荐用Halcon 20.11或更高版本因为这些版本对ARMv8的aarch64支持更完善库文件更全。获取途径如果你有正版授权从官方渠道下载Linux ARM64版本的安装包。注意要选Linux aarch64的包不是x86_64的。下载下来通常是一个.run文件或者.tar.gz压缩包。如果你只是评估学习官方提供试用版申请流程这里不展开按官方指引操作即可。安装包解压后目录结构大概是这样halcon-20.11.0.0-arm64/ ├── bin/ │ └── aarch64-linux/ │ ├── hdevelop │ └── ... ├── lib/ │ └── aarch64-linux/ │ ├── libhalcon.so │ ├── libhalconcpp.so │ └── ... ├── include/ │ ├── Halcon.h │ ├── HalconCpp.h │ └── ... └── license/关键就是lib/aarch64-linux/下的动态库和include/下的头文件。后面CMake配置主要就是指向这两个目录。3. Halcon在ARM平台的部署细节3.1 依赖库的补齐Halcon在Linux上跑依赖一堆系统库。在x86上这些通常自动装好了但在ARM的Ubuntu Server上很多库默认没装。我整理了一份必须装的依赖清单sudo apt install -y libusb-1.0-0 libusb-1.0-0-dev \ libgl1-mesa-glx libglu1-mesa libglib2.0-0 \ libx11-6 libxext6 libxrender1 libxtst6 \ libfontconfig1 libfreetype6 libpng16-16 \ libtiff5 libjpeg-turbo8 libavcodec58 libavformat58 \ libswscale5 libopenblas-dev liblapack-dev这里面有几个是重点。libusb是给加密狗用的如果你用USB license必须装。libGL系列是Halcon的图形显示模块依赖的即使你跑无头模式headless某些算子内部还是会调用图形库不装会报奇怪的错误。libopenblas和liblapack是矩阵运算加速库Halcon的部分算子会用到装了之后性能有提升。实操心得装完依赖后用ldd检查Halcon的主库有没有缺失的依赖。命令是ldd libhalcon.so | grep not found如果有输出说明还缺库根据提示补装。3.2 License的配置Halcon的license机制分两种硬件加密狗和软授权文件。树莓派上USB口有限用加密狗会占一个口而且供电可能不够稳定。我推荐用软授权把license文件放到指定目录。软授权的配置步骤# 创建license目录 sudo mkdir -p /opt/halcon/license # 把license文件复制进去 sudo cp license.dat /opt/halcon/license/ # 设置环境变量 export HALCONLICENSEDIR/opt/halcon/license环境变量要写进~/.bashrc或者/etc/profile不然每次开终端都要重新设。写进~/.bashrcecho export HALCONLICENSEDIR/opt/halcon/license ~/.bashrc echo export HALCONROOT/opt/halcon ~/.bashrc echo export LD_LIBRARY_PATH$HALCONROOT/lib/aarch64-linux:$LD_LIBRARY_PATH ~/.bashrc source ~/.bashrcLD_LIBRARY_PATH这个很关键它告诉系统去哪里找Halcon的动态库。不设的话运行时会报error while loading shared libraries: libhalcon.so: cannot open shared object file。注意license文件是和硬件绑定的通常绑MAC地址或者CPU序列号。换设备或者换网卡后license会失效需要重新申请。这一点在产品化时要提前规划。3.3 验证Halcon库能否正常加载在写代码之前先做个最小验证确认库能加载、license能识别。写一个最简单的C程序// test_halcon.cpp #include HalconCpp.h #include iostream using namespace HalconCpp; int main() { try { // 打印Halcon版本 HTuple version; GetSystem(version, version); std::cout Halcon version: version.S() std::endl; // 测试一个简单算子 HTuple width, height; GetSystem(width, width); GetSystem(height, height); std::cout System width: width.I() std::endl; std::cout Halcon loaded successfully! std::endl; } catch (HException e) { std::cerr Halcon error: e.ErrorMessage().Text() std::endl; return -1; } return 0; }编译命令g test_halcon.cpp -o test_halcon \ -I/opt/halcon/include \ -I/opt/halcon/include/halconcpp \ -L/opt/halcon/lib/aarch64-linux \ -lhalcon -lhalconcpp \ -Wl,-rpath,/opt/halcon/lib/aarch64-linux-Wl,-rpath这个参数是把库路径写进可执行文件这样运行时不用依赖LD_LIBRARY_PATH更稳妥。跑起来如果输出Halcon版本号说明库和license都没问题。如果报license错误检查HALCONLICENSEDIR是否设对license文件是否匹配当前硬件。4. CMake工程配置实战4.1 为什么用CMake而不是直接g小demo用g一行命令搞定但实际项目里源文件多、依赖复杂、还要跨平台手写编译命令不现实。CMake是C项目的事实标准Halcon官方也提供了CMake的查找模块FindHalcon.cmake虽然ARM上需要自己调整路径但整体框架是现成的。用CMake的另一个好处是方便集成其他库。实际视觉项目里你可能还要用OpenCV做预处理、用Qt做界面、用Eigen做矩阵运算CMake的find_package机制能把这些统一管理起来。4.2 完整的CMakeLists.txt配置下面是我实际项目里用的CMakeLists.txt经过多次调整在树莓派4B上跑得很稳cmake_minimum_required(VERSION 3.16) project(HalconPiVision VERSION 1.0.0 LANGUAGES CXX) # 设置C标准 set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 编译类型Release开优化 if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() set(CMAKE_CXX_FLAGS_RELEASE -O3 -marcharmv8-a -mtunecortex-a72) # Halcon路径配置 set(HALCON_ROOT /opt/halcon CACHE PATH Halcon installation root) set(HALCON_INCLUDE_DIR ${HALCON_ROOT}/include) set(HALCON_LIB_DIR ${HALCON_ROOT}/lib/aarch64-linux) # 检查Halcon是否存在 if(NOT EXISTS ${HALCON_LIB_DIR}/libhalcon.so) message(FATAL_ERROR Halcon library not found at ${HALCON_LIB_DIR}) endif() # 头文件路径 include_directories( ${HALCON_INCLUDE_DIR} ${HALCON_INCLUDE_DIR}/halconcpp ) # 库路径 link_directories(${HALCON_LIB_DIR}) # 源文件 set(SOURCES src/main.cpp src/vision_processor.cpp src/image_utils.cpp ) # 生成可执行文件 add_executable(halcon_pi_vision ${SOURCES}) # 链接Halcon库 target_link_libraries(halcon_pi_vision halconcpp halcon pthread dl ) # 设置rpath避免运行时找不到库 set_target_properties(halcon_pi_vision PROPERTIES BUILD_RPATH ${HALCON_LIB_DIR} INSTALL_RPATH ${HALCON_LIB_DIR} ) # 安装规则 install(TARGETS halcon_pi_vision DESTINATION bin)几个关键点解释一下。-marcharmv8-a -mtunecortex-a72这两个编译选项是针对树莓派4B的CPU优化的。-march指定指令集架构-mtune针对具体核心做调度优化。实测下来比默认编译快10%到15%特别是循环密集的图像处理代码。BUILD_RPATH和INSTALL_RPATH是设置运行时库搜索路径。这样编译出来的可执行文件不管在哪个目录跑都能找到Halcon的库不用手动设LD_LIBRARY_PATH。pthread和dl是Halcon内部用到的必须链接不然会有未定义符号的错误。4.3 编译与运行配置和编译mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease make -j4-j4是四核并行编译树莓派4B正好四核能明显加快编译速度。第一次编译Halcon相关代码可能要几分钟后面增量编译就快了。编译完成后可执行文件在build/目录下。直接运行./halcon_pi_vision如果报找不到库用ldd halcon_pi_vision | grep halcon检查正常情况下应该显示库的完整路径。如果显示not found说明rpath没生效检查CMakeLists里的路径是否正确。实操心得如果项目里同时用OpenCV和Halcon注意两者的头文件可能有命名冲突比如都有Point、Rect之类的类型。解决办法是用命名空间隔离Halcon的用HalconCpp::OpenCV的用cv::不要用using namespace。5. 性能调优与实测数据5.1 树莓派4B上的性能基线光跑通不算完得知道性能到底怎么样。我用几个典型视觉任务做了实测数据如下Halcon 20.11Ubuntu 20.04 64位8GB版本开启风扇不降频任务类型图像分辨率耗时备注图像读取灰度转换2592x194445ms从SD卡读图高斯滤波2592x1944120mssigma2.0边缘检测Canny2592x1944180ms双阈值形状匹配单模板1280x96095ms模板200x200形状匹配多模板10个1280x960620ms并行度4亚像素测量1280x960210ms卡尺工具深度图转点云640x480350ms含三角化这些数据是在理想条件下测的实际项目里还要加上图像采集、通信、结果输出的时间。整体来看树莓派4B能胜任中等分辨率的实时检测任务帧率大概在3到10帧之间取决于算法复杂度。如果要求更高帧率要么降分辨率要么用Jetson Nano这类带GPU的平台。5.2 几个实用的优化手段第一图像分辨率能降就降。视觉算法的耗时和像素数基本成正比。如果检测目标不大没必要用全分辨率裁剪ROI或者降采样能省大量时间。我有个项目原来用500万像素跑后来改成先降采样到200万做粗定位再在原图ROI上做精测量整体耗时降了60%。第二善用Halcon的并行算子。Halcon很多算子支持多线程比如find_shape_model可以设NumLevels和Greediness来平衡速度和精度。树莓派4B四核把parallelize_operators打开能利用多核。但注意别开太多线程内存带宽是瓶颈开4个线程通常就够了。第三减少图像在内存和磁盘之间的搬运。能用内存缓存就别写磁盘能用共享内存就别拷贝。Halcon的HImage对象内部是引用计数的传参时用引用避免深拷贝。第四编译优化别省。-O3加上-marcharmv8-a -mtunecortex-a72再开-ffast-math如果算法允许浮点误差性能提升很明显。我实测一个滤波任务-O0到-O3差了将近3倍。5.3 内存管理要注意的坑Halcon在ARM上的内存管理和x86有些差异。最明显的是大图像处理时的内存峰值。比如做金字塔匹配Halcon会创建多层图像内存占用是原图的1.5到2倍。树莓派4B的8GB看着多但系统本身占1GB左右实际可用7GB处理超大图或者多任务并发时容易OOM。解决办法及时释放不用的HImage和HRegion对象用ClearObj显式清理。另外可以设置Halcon的内存池大小通过set_system算子调整。我一般会把image_cache设小一点避免缓存占太多内存。注意树莓派4B的USB 3.0和千兆网口共享带宽如果同时用USB摄像头和网络传输带宽会打架。做高帧率采集时要么用CSI摄像头走专用接口要么把网络传输错开。6. 常见问题与排查实录6.1 库加载失败类问题问题运行时报libhalcon.so: cannot open shared object file这是最常见的问题原因就三个库路径没设对、rpath没生效、或者库文件本身缺失。排查步骤# 1. 确认库文件存在 ls -la /opt/halcon/lib/aarch64-linux/libhalcon.so # 2. 检查可执行文件的rpath readelf -d ./halcon_pi_vision | grep RPATH # 3. 检查依赖是否完整 ldd ./halcon_pi_vision | grep not found如果rpath是空的说明CMake里的BUILD_RPATH没生效检查CMake版本是否支持3.16以上都支持。如果依赖有not found按提示补装对应的库。问题HALCON error #2106: License file not foundlicense路径不对或者文件不匹配。检查HALCONLICENSEDIR环境变量确认license文件在那个目录下。另外注意license文件要有读权限chmod 644。6.2 编译链接类问题问题undefined reference to HalconCpp::HImage::HImage()链接顺序问题。Halcon的库有依赖关系halconcpp依赖halcon所以链接时halconcpp要写在halcon前面。CMake的target_link_libraries里顺序就是链接顺序别搞反。问题编译时提示找不到HalconCpp.h头文件路径没配对。Halcon的头文件在include/和include/halconcpp/两个目录下两个都要加到include路径里。有些版本的头文件组织方式不同用find命令确认一下find /opt/halcon -name HalconCpp.h6.3 运行时异常类问题问题程序跑着跑着崩溃报Segmentation faultARM平台上的段错误常见原因有几个。一是图像数据对齐问题Halcon某些算子要求图像行字节对齐到特定边界不对齐会崩。解决办法是用gen_image1创建图像时确保width是4的倍数。二是多线程竞争Halcon的某些全局状态不是线程安全的多线程调用时要加锁。三是内存越界检查图像访问的坐标是否超出范围。问题HALCON error #1203: Wrong image size图像尺寸和算子要求不匹配。比如某些算子要求图像宽高是偶数或者有最小尺寸限制。查Halcon文档确认算子的尺寸要求必要时先做padding或者resize。6.4 常见问题速查表现象可能原因排查方法解决方案库加载失败路径未设/rpath缺失ldd检查设LD_LIBRARY_PATH或rpathLicense错误路径不对/文件不匹配检查环境变量重新配置license链接错误库顺序错/缺库看错误符号调整链接顺序段错误内存越界/对齐问题gdb调试检查图像尺寸和对齐性能差未开优化/降频看CPU频率开-O3/加散热内存不足图像太大/泄漏free -h监控降分辨率/及时释放实操心得调试Halcon程序时把set_system(debug, true)打开Halcon会输出详细的内部日志定位问题快很多。但正式发布时要关掉日志会影响性能。7. 从跑通到产品化的几点思考7.1 部署架构的选择跑通demo和做成产品是两回事。产品化时Halcon程序通常不是独立运行的而是作为视觉服务嵌入到整个系统里。常见的架构有两种。一种是本地处理树莓派上跑完整的视觉流程结果通过GPIO或者串口输出给执行机构。这种架构简单、延迟低适合单机设备。另一种是边缘加云端树莓派做图像采集和预处理复杂算法上传到服务器处理。这种架构适合算法更新频繁或者算力要求高的场景但对网络依赖大。我自己的项目用的是本地处理因为检测节拍要求高网络传输的延迟不可控。树莓派4B的算力虽然有限但把算法优化好满足中等复杂度的检测是够的。7.2 稳定性与看门狗嵌入式设备跑视觉稳定性是第一位的。树莓派不是工业级硬件长时间运行可能因为温度、电源波动、SD卡老化出问题。几个加固措施用看门狗定时器监控进程挂了自动重启用只读文件系统保护SD卡减少写操作加UPS或者稳压电源避免突然断电导致文件系统损坏。Halcon程序本身也要做异常处理。所有算子调用都包在try-catch里出错时记录日志并优雅退出不要直接崩。我一般会写一个全局的异常处理器把Halcon的HException转成自定义的错误码方便上层系统处理。7.3 算法移植的注意事项如果你有x86上跑好的Halcon算法要移植到树莓派有几个地方要特别注意。浮点精度ARM和x86的浮点运算结果可能有微小差异对精度敏感的测量算法要重新验证。算子支持不是所有Halcon算子都在ARM上有优化实现某些算子可能走的是通用路径性能差很多。移植前用get_system(operators)查一下算子的支持情况。图像格式x86上常用的某些图像格式在ARM上可能不支持统一用Halcon的原生格式最稳妥。7.4 成本与收益的平衡最后说点现实的。树莓派4B加Halcon license的成本和一台低端工控机加Windows加Halcon比硬件省了不少但license成本是一样的。所以这个方案的经济性主要体现在硬件体积、功耗、部署灵活性上而不是license费用。如果你的场景对体积和功耗不敏感用工控机可能更省心。但如果你做的是移动设备、嵌入式终端、或者需要大量分布式部署的检测点树莓派方案的优势就出来了。一个检测点几百块硬件成本铺几十个点也不心疼这是工控机做不到的。我在实际项目里最终选了树莓派方案跑了半年多稳定性满足要求维护成本也低。踩过的坑基本都在上面写了希望对后来者有帮助。如果你在部署过程中遇到上面没覆盖的问题大概率是环境差异导致的按排查思路一步步来总能解决。
返回列表