ARTICLE DETAIL

资讯详情

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

使用 C API 开发 RealSense 无头(Headless)应用:Depth、Color 与 Distance 示例深度解析

使用 C API 开发 RealSense 无头(Headless)应用:Depth、Color 与 Distance 示例深度解析 使用 C API 开发 RealSense 无头Headless应用Depth、Color 与 Distance 示例深度解析【免费下载链接】librealsenseRealSense SDK项目地址: https://gitcode.com/GitHub_Trending/li/librealsense导读本文以 examples/C/readme.md 为主线系统讲解 Intel RealSense SDKlibrealsense中面向C 语言的纯命令行示例rs-depth深度流文本可视化、rs-color彩色流帧信息打印与rs-distance画面中心物体距离测量。这三个示例不依赖任何图形界面非常适合在服务器、嵌入式板卡等无头环境下快速验证相机、接入 SDK 并获取深度与彩色数据。读完本文你将掌握 C API 的设备枚举、Pipeline 配置、帧同步获取、深度单位换算与中心点测距等核心编程套路可直接复制到自己的工程中。一、示例概览三分钟跑通 C 版 SDKexamples/C目录下的示例全部使用librealsense2的纯 C 接口头文件位于 include/librealsense2/rs.h与 C 的rs2::封装相比C API 以rs2_前缀函数 rs2_error*错误指针的形式工作风格更接近底层、依赖更少适合嵌入到 C 项目中。示例源码核心能力难度Depthexamples/C/depth/rs-depth.c深度流 终端 ASCII 可视化★★Colorexamples/C/color/rs-color.c彩色流 帧信息打印★Distanceexamples/C/distance/rs-distance.c深度流 画面中心点测距★Infrared补充examples/C/infrared左右红外流 ASCII 可视化★★其中Distance与 C 示例hello-realsense功能等价可视为 C 用户的入门第一课见 examples/readme.md 的示例总表Depth则是无头环境下验证深度数据质量的实用工具。社区贡献方面原文档还提到了minimal_realsense2项目展示 C 语言的流式传输与预置配置可在社区代码中检索获取。二、构建方式如何编译这些 C 示例2.1 通过顶层 CMake 构建所有 C 示例都已接入主构建系统。在 examples/CMakeLists.txt 中可以看到它们通过add_subdirectory(C/depth)、add_subdirectory(C/color)、add_subdirectory(C/distance)、add_subdirectory(C/infrared)被纳入整体构建并以rs-depth、rs-color、rs-distance等可执行文件名产出。以 examples/C/depth/CMakeLists.txt 为例单个示例的构建逻辑非常简洁cmake_minimum_required(VERSION 3.10) project(RealsenseExamples-Depth) # 将编译命令导出到构建输出便于调试 set(CMAKE_EXPORT_COMPILE_COMMANDS 1) add_executable(rs-depth rs-depth.c ../example.h) include_directories(../../C) target_link_libraries(rs-depth ${DEPENDENCIES}) install(TARGETS rs-depth RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})关键点在于include_directories(../../C)使示例能够引用共享头文件 examples/C/example.htarget_link_libraries(rs-depth ${DEPENDENCIES})则链接到主 SDK 目标LRS_TARGET即realsense2库。整体编译与安装流程可参照 doc/installation.md。2.2 三个示例共用的辅助头文件examples/C/example.h 提供了两个贯穿全部示例的辅助函数check_error(rs2_error* e)所有 C API 调用都可能抛出rs_error该函数在出错时打印失败函数名rs2_get_failed_function、参数rs2_get_failed_args与错误消息rs2_get_error_message后退出print_device_info(rs2_device* dev)打印当前使用设备的名称、序列号与固件版本分别对应RS2_CAMERA_INFO_NAME、RS2_CAMERA_INFO_SERIAL_NUMBER、RS2_CAMERA_INFO_FIRMWARE_VERSION。这段代码体现了 C API 的通用错误处理范式——每个函数调用都传入一个rs2_error*指针调用后必须检查其是否非空这也是后续所有示例代码共有的骨架。三、C API 通用骨架从设备枚举到帧同步三个示例的main()结构几乎一致构成了 C 语言使用 librealsense 的标准五步创建上下文rs2_create_context(RS2_API_VERSION, e)创建持有所有已连接设备句柄的上下文对象用后须rs2_delete_context释放枚举设备rs2_query_devices(ctx, e)返回设备列表rs2_get_device_count统计数量rs2_create_device(device_list, 0, e)取出第一台设备。若列表为空dev_count 0程序直接返回EXIT_FAILURE这正是无头环境下的典型健壮性检查创建 Pipeline 与 Configrs2_create_pipeline(ctx, e)创建负责配置—启动—停止流式传输的管道rs2_create_config(e)创建配置对象通过rs2_config_enable_stream(...)指定期望的流启动管道rs2_pipeline_start_with_config(pipeline, config, e)按配置启动流式传输并返回rs2_pipeline_profile描述实际生效的流配置。若设备不支持所请求的流例如无深度传感器的型号该调用会置位错误指针示例会打印提示并退出同步取帧在while(1)循环中调用rs2_pipeline_wait_for_frames(pipeline, RS2_DEFAULT_TIMEOUT, e)阻塞等待新帧。RS2_DEFAULT_TIMEOUT在 include/librealsense2/h/rs_config.h 中定义为15000毫秒即最长等待 15 秒。3.1 复合帧composite_frame处理rs2_pipeline_wait_for_frames返回的不是单帧而是一个复合帧——它同时承载深度、彩色、红外等多个子帧这种设计用于避免帧丢失。示例通过以下三个函数完成拆包rs2_embedded_frames_count(frames, e)统计复合帧内嵌的子帧数量rs2_extract_frame(frames, i, e)取出第i个子帧rs2_release_frame(frame)释放帧资源。所有帧对象包括外层复合帧都必须显式释放否则会持续占用内存这是 C API 与 C RAII 封装最大的使用差异。四、rs-depth深度流 终端 ASCII 可视化4.1 可配置的流参数examples/C/depth/rs-depth.c 开头用宏集中定义了流的全部参数改这几行即可切换分辨率、帧率与格式#define STREAM RS2_STREAM_DEPTH // 数据类型深度流 #define FORMAT RS2_FORMAT_Z16 // 编码格式16 位无符号深度值 #define WIDTH 640 // 帧宽0 表示自动选择 #define HEIGHT 0 // 帧高0 表示自动选择 #define FPS 30 // 帧率 #define STREAM_INDEX 0 // 流索引用于区分同类型多路流 #define HEIGHT_RATIO 20 // 可视化时高度方向的像素聚合比 #define WIDTH_RATIO 10 // 可视化时宽度方向的像素聚合比其中RS2_FORMAT_Z16表示每个像素用 16 位无符号整数存储深度值单位由相机的depth units决定见 4.2 节。HEIGHT0时由 SDK 依据宽度自动解析出配套高度这是让配置保持尽力而为的常见写法。4.2 深度单位换算get_depth_unit_value深度原始值不是直接以米为单位的。get_depth_unit_value()函数通过遍历设备传感器列表找到可扩展为RS2_EXTENSION_DEPTH_SENSOR的深度传感器再读取其RS2_OPTION_DEPTH_UNITS选项值。该选项在 include/librealsense2/h/rs_option.h 中的定义为单个深度单位所代表的米数源码中默认回退值为0.001f即毫米精度。据此示例计算1 米对应的原始深度值uint16_t one_meter (uint16_t)(1.0f / get_depth_unit_value(dev));若depth units 0.001则one_meter 1000——即原始深度读数 1000 代表 1 米。这是后续所有深度像素判断的换算基准。4.3 文本可视化算法拿到Z16深度数据后示例采用分块直方图思路在终端渲染出一幅 ASCII 深度图以WIDTH_RATIO10、HEIGHT_RATIO20将画面划分为 10×5 像素的块rows height / 20row_length width / 10对每个像素若其深度值0 depth one_meter即在 1 米范围内则将对应列的coverage计数加一从而为每一行块建立深度直方图每累积HEIGHT_RATIO行后依据覆盖率映射到 ASCII 字符集 .:nhBXWW从空格到W共 9 级越靠后表示覆盖越密集逐块输出并换行。最终终端上会持续刷新一帧近处物体密度图W多的区域即表示 1 米内有大量像素覆盖。这个不依赖 GUI 的实现思路是嵌入式/无头环境下肉眼检查深度数据的经典技巧。提示运行该程序前建议为设备安装 udev 规则见 config/99-realsense-libusb.rules否则非 root 用户可能无法访问 USB 设备。五、rs-color彩色流与帧元数据打印examples/C/color/rs-color.c 演示了最简配置——完全不指定具体参数全部交给 SDK 自动解析#define STREAM RS2_STREAM_COLOR // 彩色流 #define FORMAT RS2_FORMAT_ANY // 任意格式 #define WIDTH 0 // 自动 #define HEIGHT 0 // 自动 #define FPS 0 // 自动 #define STREAM_INDEX -1 // 任意索引注意STREAM_INDEX在此处为-1表示任意索引与 depth 示例的0形成对比前者只关心来一路彩色流就行后者则明确锁定第 0 路深度流。启动成功后示例对每一帧彩色数据提取并打印以下信息帧号rs2_get_frame_number(frame, e)用于判断帧是否连续、是否丢帧时间戳rs2_get_frame_timestamp(frame, e)返回rs2_time_t浮点秒时间戳域rs2_get_frame_timestamp_domain(frame, e)返回rs2_timestamp_domain枚举指示时间戳是基于硬件时钟如RS2_TIMESTAMP_DOMAIN_HARDWARE_CLOCK还是系统时钟再经 include/librealsense2/h/rs_frame.h 声明的rs2_timestamp_domain_to_string转为可读字符串到达时间rs2_get_frame_metadata(frame, RS2_FRAME_METADATA_TIME_OF_ARRIVAL, e)读取帧元数据中的到达主机时刻该值依赖相机固件对元数据metadata的支持是分析端到端延迟的重要依据前 10 字节裸数据rs2_get_frame_data(frame, e)返回帧缓冲指针示例按字节打印前 10 个十六进制值直观展示原始像素布局。这段代码集中展示了帧对象rs2_frame*上最常用的一组信息查询接口是理解 include/librealsense2/h/rs_frame.h 中帧 API 的良好起点。六、rs-distance画面中心物体测距examples/C/distance/rs-distance.c 在 depth 示例的基础上大幅简化——它不做可视化而是直接回答相机正对着的物体有多远。配置部分与 depth 示例相同RS2_STREAM_DEPTHRS2_FORMAT_Z16 640×030fps核心区别在取帧后的处理// 检查是否为深度帧跳过其他类型的子帧 if (0 rs2_is_frame_extendable_to(frame, RS2_EXTENSION_DEPTH_FRAME, e)) continue; // 获取帧宽高 int width rs2_get_frame_width(frame, e); int height rs2_get_frame_height(frame, e); // 查询画面中心像素的距离单位米 float dist_to_center rs2_depth_frame_get_distance(frame, width / 2, height / 2, e); printf(The camera is facing an object %.3f meters away.\n, dist_to_center);rs2_is_frame_extendable_to与 depth 示例中rs2_extract_frame后的RS2_EXTENSION_DEPTH_FRAME检查一脉相承用于在复合帧中筛选出深度帧rs2_depth_frame_get_distance接受像素坐标并直接返回以米为单位的距离内部已完成depth units换算并会处理无效/超出范围的深度值因此输出可直接使用%.3f格式化为三位小数。该示例的实战意义在于它把深度原始值与物理距离之间的转换封装在了 SDK 内部用户只需关心像素坐标即可适合快速搭建避障、测距、跟随等应用的原型。七、延伸rs-infrared —— 双目红外流的文本可视化虽然 examples/C/readme.md 只列出了三个示例但examples/C目录下还包含第四个示例 examples/C/infrared。根据其 readme.md它演示了枚举并区分左红外IR1与右红外IR2两路流以Y8格式8 位灰度配置并启动红外流类似 depth 示例的分块思路将左右两路红外图像的强度等级用 ASCII 字符并排渲染到终端。对于双目立体视觉相机如 D400 系列同时观察左右红外图是排查深度空洞、标定异常的常用手段该示例补全了 C 示例集中对多路同类型流STREAM_INDEX区分的覆盖。八、总结无头 C 开发的要点清单错误处理每个rs2_*调用都传入rs2_error*并立刻检查这是 C API 的纪律性要求资源管理context、device_list、device、pipeline、config、pipeline_profile、frame等对象均需按注释调用对应的rs2_delete_*/rs2_release_frame释放深度单位原始Z16读数必须结合RS2_OPTION_DEPTH_UNITS换算成米rs2_depth_frame_get_distance可直接返回米制距离复合帧wait_for_frames返回复合帧需用rs2_embedded_frames_countrs2_extract_frame拆包并用rs2_is_frame_extendable_to按需过滤帧类型无头运行三个示例全程不依赖窗口系统任何具备终端的环境服务器、Jetson、树莓派都可直接运行是快速验证相机连通性与数据质量的第一站。在此基础上若需要更底层的控制可进一步阅读 src/pipeline 中的 C 管道实现或借助 examples 下的 C 示例如 examples/pointcloud、examples/save-to-disk了解对齐、点云与离线录制等进阶能力。【免费下载链接】librealsenseRealSense SDK项目地址: https://gitcode.com/GitHub_Trending/li/librealsense创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表