RGBD深度相机数据格式-存储读取-可视化

本文介绍了RGBD相机的工作原理,详细讲解了数据格式、存储读取方法和深度图的可视化技术,包括如何从深度数据获取三维坐标以及应用ColorMap进行颜色映射。并提供了OpenNI接口的使用示例,帮助理解RGBD相机数据处理的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设备

此处RGBD相机主要指利用Light Coding(结构光)或TOF进行成像的深度相机,主动发光,主要适用于室内环境。

比较常见的RGBD相机如下表:

相机 原理 SDK 资料
PrimeSense Carmine 1.08/1.09 (2012) Light Coding(散斑) OpenNI 链接
Xbox One Kinect(Kinect v2,2013) TOF OpenNI/Kinect SDK
ASUS XTION 2 / XTION PRO LIVE(CARMINE 1.08的马甲) Light Coding OpenNI 链接
Intel RealSense(D435 etc.) Light Coding(编码) OpenNI/Realsense Camera SDK 链接
ZED (2016) Stereo

数据格式

通常深度数据使用整形数进行表示,范围在0-65535之间,类型为UINT16,即unsigned short,无符号2字节
单位为毫米(mm),但是某些SDK也支持使用100微米(um)来进行表示,如OpenNI支持的深度数据格式有PIXEL_FORMAT_DEPTH_1_MM,PIXEL_FORMAT_DEPTH_100_UM等。至于分辨率则通常是万年的640x480,有些甚至是320x240插值上去的。

由于Depth有一定的有效工作范围,以PrimeSense Carmine 1.09为例,其工作范围只有0.35-1.4m,即数据范围是350-1400,通常会使用一个数值来表示无效的数据,如0或65535。

通常RGB Sensor和Depth Sensor的FOV并不一致,所以需要进行配准,配准的目的是使得RGB的像素和Depth的像素一一对应。谁向谁来配准倒是没有那么重要,深度图也可以被插值,与彩色图类似。

以OpenNI为例,里面有一个这样的接口,setImageRegistrationMode(IMAGE_REGISTRATION_DEPTH_TO_COLOR),其效果是裁剪缩放深度图使得其FOV与RGB完全相同(但其实边缘已经没有了,全部都是无效的Depth像素)。

存储读取

根据之前的描述,深度图的表示也很简单,如下:

char RGBData[640][480][3];
typedef unsigned short UINT16,*PUINT16;
UINT16 DepthData[640][480];

我们可以自己实现保存与读取的方法,也可以借助一些第三方SDK,如OpenCV进行读写,
在操作深度图时,OpenCV使用的格式是CV_16U,举个例子:

inline cv::Mat getMat(const VideoFrameRef &frame,int dataStride,int openCVFormat){
   
   
    //深度图PNG16类型(short),Little-Endian(低位在低字节)
    //RGB图BGR24类型
    int h=frame.getHeight();
    int w=frame.getWidth();
    cv::Mat image=cv::Mat(h,w,openCVFormat);
    memcpy(image.data,frame.getData(),h*w*dataStride);
    //cv::flip(image,image,1);
    return image
### STM32CubeMX FreeRTOS CAN Queue Read Example #### 配置项目环境 为了实现基于FreeRTOS的CAN消息队列读取,在STM32CubeMX环境中需完成以下设置: - 使用STM32CubeMX创建新工程并选择目标MCU型号。 - 启用CAN外设支持,并通过RTE(Run-Time Environment)配置其参数,如波特率等。 - 添加对FreeRTOS的支持,这会自动引入必要的库文件和初始化代码。 #### 初始化FreeRTOS与CAN模块 确保已正确设置了`FreeRTOSConfig.h`中的各项参数以适应应用需求[^1]。对于CAN通信部分,则要依据具体硬件平台调整相应的初始化函数调用,通常位于`main.c`或其他由开发者指定的位置。 ```c // main.c or other designated file #include "cmsis_os.h" #include "can.h" osThreadId canReceiveTaskHandle; osMessageQueueId canMsgQueue; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_CAN1_Init(void); int main(void){ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_CAN1_Init(); osKernelInitialize(); // Initialize CMSIS-OS V2 RTX Kernel // Create the message queue capable of holding up to 10 messages. canMsgQueue = osMessageQueueNew(10, sizeof(CAN_RxHeaderTypeDef), NULL); // Start thread as specified. canReceiveTaskHandle = osThreadNew(can_receive_task, NULL, NULL); osKernelStart(); } ``` #### 创建接收任务处理程序 定义一个专门的任务用于监听来自CAN总线的数据包并通过预先建立的消息队列传递给其他组件进一步解析或响应。 ```c #define MSG_QUEUE_TIMEOUT (10) void can_receive_task(void *argument) { uint8_t rxData[8]; CAN_RxHeaderTypeDef RxHeader; while (true) { if(HAL_CAN_GetRxMessage(&hcan1,&RxHeader,rxData)==HAL_OK){ // Put received data into a queue for processing by another task. osMessageQueuePut(canMsgQueue, &RxHeader, 0, MSG_QUEUE_TIMEOUT); /* Process Data Here */ } osDelay(1); // Short delay between checks } } ``` 上述代码片段展示了如何利用FreeRTOS提供的APIs构建一个多线程应用程序框架下的CAN报文接收机制。每当接收到新的数据帧时即刻将其存入共享资源——消息队列之中等待后续操作;与此同时保持较低优先级循环执行以便让渡CPU时间片给更高紧迫性的作业单元[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值