arm64架构开发板上调用奥比中光深度摄像头用于视觉测距
1.Orbbec Gemini 深度摄像头简介
本文使用的是Orbbec Gemini版本摄像模组,其具备双目红外深度摄像模快,因此可以用于视觉精准测距。它通过同时采集红外图像与深度图,实现空间三维信息的获取,可以广泛应用于人脸识别、手势交互、三维建模等领域。
利用红外双目/结构光原理,深度摄像头模块可以通过两个红外摄像头采集同一场景,从视差中恢复深度图像。
同时,摄像模组提供 C++/Python 等多语言 SDK 接口,可实时访问彩色图、深度图、点云等数据,也可以自主编写调用用于视觉测距模块。
本文主要使用双目红外深度摄像模块,移植代码于arm64架构的开发板上(使用openeuler系统的海思SS928算力开发板);实现基础测距功能。
本移植过程主要思路为在ubuntu主机实现交叉编译,将编译结果与环境库移植进入开发板。
2.SDK文件下载
https://github.com/orbbec/OrbbecSDK/releaseshttps://github.com/orbbec/OrbbecSDK/releases奥比中光在github上提供了官方的SDK资料,可供下载;
选择相机适配的版本,以及运行环境适配的系统与架构。
根据本需求(gemini相机部署于linux arm64架构平台),
选择OrbbecViewer_v1.10.22_202504111013_arm64_release.zip压缩包下载、解压。
3.移植过程
进入ubuntu主机下的解压后SDK目录;
对于深度图像提取距离信息而言,我们可以直接进入Example>cpp>DepthViewer目录:
官方提供了基本的cpp程序与编译文件。
笔者根据需求建立了新的文件进行自主编译:
创建新的 DepthViewer.cpp 文件
#include "libobsensor/hpp/Pipeline.hpp"
#include "libobsensor/hpp/Error.hpp"
#include <libobsensor/hpp/Frame.hpp>
#include <iostream>
#include <memory>int main(int argc, char **argv) try {// 创建默认设备的 Pipelineob::Pipeline pipe;// 创建配置并启用深度流std::shared_ptr<ob::Config> config = std::make_shared<ob::Config>();config->enableVideoStream(OB_STREAM_DEPTH);// 启动 Pipelinepipe.start(config);while (true) {// 阻塞等待帧,超时100msauto frameSet = pipe.waitForFrames(100);if (frameSet == nullptr) {continue;}auto depthFrame = frameSet->depthFrame();// 每30帧输出一次中间像素距离if (depthFrame->index() % 30 == 0 && depthFrame->format() == OB_FORMAT_Y16) {uint32_t width = depthFrame->width();uint32_t height = depthFrame->height();float scale = depthFrame->getValueScale();uint16_t *data = (uint16_t *)depthFrame->data();float centerDistance = data[width * height / 2 + width / 2] * scale;std::cout << "Center pixel distance: " << centerDistance << " mm" << std::endl;}}// 停止 Pipelinepipe.stop();return 0;
}
catch (ob::Error &e) {std::cerr << "function: " << e.getName()<< "\nargs: " << e.getArgs()<< "\nmessage: " << e.getMessage()<< "\ntype: " << e.getExceptionType()<< std::endl;exit(EXIT_FAILURE);
}
修改编译文本 CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)# 设置交叉编译器
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)project(orbbec_distance_sample LANGUAGES CXX)# 指定交叉编译工具链(根据你使用的工具链具体路径调整)
# 或者在命令行 `cmake` 时指定 -DCMAKE_TOOLCHAIN_FILE=xxx.toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_FIND_ROOT_PATH /home/why/arm-sysroot)# 编译选项
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall")# 设置输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY /home/why/Orbbec/OrbbecSDK_v1.10.22/Ex/bin)# SDK 相关路径
set(OrbbecSDK_INCLUDE_DIR /home/why/Orbbec/OrbbecSDK_v1.10.22/SDK/include)
set(OrbbecSDK_LIBRARY_DIR /home/why/Orbbec/OrbbecSDK_v1.10.22/SDK/lib)include_directories(${OrbbecSDK_INCLUDE_DIR})
link_directories(${OrbbecSDK_LIBRARY_DIR})# 添加源码
add_executable(sample DepthViewer_new.cpp)# 链接 obsensor SDK 库
target_link_libraries(sample /home/why/Orbbec/OrbbecSDK_v1.10.22/SDK/lib/libOrbbecSDK.so.1.10.22)
注意根据实际情况修改;
注意这里的各种库文件及地址:
set(CMAKE_FIND_ROOT_PATH /home/why/arm-sysroot)
设置交叉编译环境的各种库(根据代码需求)
# SDK 相关路径
set(OrbbecSDK_INCLUDE_DIR /home/why/Orbbec/OrbbecSDK_v1.10.22/SDK/include)
set(OrbbecSDK_LIBRARY_DIR /home/why/Orbbec/OrbbecSDK_v1.10.22/SDK/lib)
摄像头模组调用时需要的SDK各种库;位于SDK文件夹下;
# 链接 obsensor SDK 库
target_link_libraries(sample /home/why/Orbbec/OrbbecSDK_v1.10.22/SDK/lib/libOrbbecSDK.so.1.10.22)
独立链接libOrbbecSDK.so.1.10.22库;防止自动寻找找不到
在当前目录下,创建 build 文件夹,进入 build 文件夹;
执行编译
cmake ..
make
4.传输执行
编译结果的可执行性文件会出现在
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY /home/why/Orbbec/OrbbecSDK_v1.10.22/Ex/bin)
这里指定的目录下。
将可执行性文件移植到开发板,但此时我们显然缺少库文件依赖,无法直接执行;
此时我们来到库文件位置 Orbbec/OrbbecSDK_v1.10.22/SDK/lib/
拷贝目录下所有文件,打包并传输到开发板库文件位置
笔者这里传输到了usr/orbbec目录下,需要自主配置环境变量:
export LD_LIBRARY_PATH=/usr/orbbec:$LD_LIBRARY_PATH
配置成功后,在开发板端接入相机,可以直接运行可执行性文件;
注意:如果出现库文件链接报错,可以手动为库文件链接,如:
ln -sf libOrbbecSDK.so.1.10.22 libOrbbecSDK.so
ln -sf libOrbbecSDK.so.1.10.22 libOrbbecSDK.so.1.10
如果成功运行,程序会每隔零点五秒,读取一次中心点的深度图像信息,作为距离返回输出。
输出示例如: