- RealSenseTM互动开发实战
- 王曰海 汤振宇 吴新天
- 1063字
- 2025-03-27 02:04:46
2.5 坐标系统
SDK使用两种坐标系统定义:图像坐标系和摄像头坐标系。
1.图像坐标系
像素的位置坐标指的是在彩色或深度图片中像素所在的位置(x,y),其中x为0~w-1(w是图像的宽度),y为0~h-1(h是图像高度),如图2-8所示。从摄像头视图来看,原点(0,0)在左上角,x轴指向右,y轴指向下。

图2-8 图像坐标系
2.摄像头坐标系
摄像头坐标系中的坐标是三维坐标(x,y,z),原点(0,0,0)在深度摄像头的中心。如果没有特别指定,则坐标单位默认为米。
对于前置摄像头(摄像头面向用户),默认的坐标系统被定义为x轴指向右侧(摄像头视图),y轴向上,z轴面朝用户,这也被称为“左手系”,如图2-9所示。摄像头坐标系的定义并没有改变摄像头的镜像模式。

图2-9 摄像头坐标系
对于后置摄像头(摄像头朝着场景),默认的坐标系统是右手系统:x坐标轴指向用户的右侧,y轴向上,z轴朝向用户,如图2-10所示。参考系不改变摄像头的镜像模式。如无特殊规定,坐标的单位为米。

图2-10 后置摄像头默认坐标系
对于后置摄像头的另一种坐标定义方法是OpenCV摄像头坐标系。OpenCV摄像头坐标系定义为x轴指向摄像头的右侧,y轴朝下的场景,如图2-11所示。

图2-11 OpenCV摄像头坐标系
3.配置坐标系
在SDK的会话初始化时,SDK设置坐标系为默认值。可以使用QueryCoordinateSystem函数来获取当前坐标系统设置。该函数返回一个包含前置和后置摄像头的坐标系的位掩模。因此,如果需要对特定的摄像头方向检查坐标位掩模,可以参考例2-19。
例2-19 检查后置摄像头坐标系
//创建一个SenseManager实例 PXCMSenseManagersm=PXCMSenseManager.CreateInstance(); //得到坐标系设定 PXCMSession session=sm.QuerySession(); EnumSet<PXCMSession.CoordinateSystem>cs=session.QueryCoordinateSystem(); //检查后置摄像头坐标系 if (cs.contains(PXCMSession.CoordinateSystem.COORDINATE_SYSTEM_OPENCV)) { ...... } //清理 sm.close();
可以使用SetCoordinatesystem功能来改变坐标系统设置。每个SDK模块在模块的初始化过程中读取坐标系设置。必须在SDK模块或算法进行初始化时设置坐标系统,以确保模块工作在相同的坐标系统下。SenseManager在Enablexxx函数中初始化算法模块,并在Init函数中进行I/O模块的初始化。请参见例2-20中设置坐标系的相关操作。
例2-20 坐标系设置
//创建PXCMProjection实例 PXCMProjection projection=device.CreateProjection(); //获取深度和彩色图像尺寸 PXCMImage.ImageInfodinfo=depth.QueryInfo(); PXCMImage.ImageInfocinfo=color.QueryInfo(); //计算红外图 PXCMPointF32[] uvmap=new PXCMPointF32[dinfo.width*dinfo.height]; projection.QueryUVMap(depth, uvmap); //将深度点数组uv[]译为彩色数组ij[] for (inti=0;i<uv.Length;i++) { ij[i].x=uvmap[(int)uv[i].y*dinfo.width+(int)uv[i].x].x*cinfo.width; ij[i].y=uvmap[(int)uv[i].y*dinfo.width+(int)uv[i].x].y*cinfo.height; } //清理 projection.close();
4.坐标映射
由于摄像头在物理位置、镜头大小、视野方面的差异,彩色和深度图像坐标系无法做到1:1映射,因此需要使用Projection函数来映射或投影坐标系。可以使用CreateProjection函数来获取投影接口的实例。
Projection函数提供以下映射或投影:
- 彩色和深度图像坐标之间的映射。
- 在彩色、深度图像坐标和世界坐标之间的投影。
- 创建空间和大小对齐的彩色和深度图像。
例2-21展示了如何使用红外图(UV map)映射深度和彩色坐标。
例2-21 映射深度和彩色坐标
//创建PXCMProjection实例 PXCMProjection projection=device.CreateProjection(); //获取深度和颜色图像尺寸 PXCMImage.ImageInfodinfo=depth.QueryInfo(); PXCMImage.ImageInfocinfo=color.QueryInfo(); //计算红外图 PXCMPointF32[] uvmap=new PXCMPointF32[dinfo.width*dinfo.height]; projection.QueryUVMap(depth, uvmap); //将深度点数组uv[]译为颜色数组ij[] for (inti=0;i<uv.Length;i++) { ij[i].x=uvmap[(int)uv[i].y*dinfo.width+(int)uv[i].x].x*cinfo.width; ij[i].y=uvmap[(int)uv[i].y*dinfo.width+(int)uv[i].x].y*cinfo.height; } //清理 projection.close();