![]() |
OpenNI2 SDK
v2.3.0.81
|
通过不同原理(主流:结构光、iToF、双目)进行测量,通过处理这些测量值可以生成深度图。 深度图是图像每个像素的一组 Z 坐标值,单位为毫米。
测量物体三轴姿态角及加速度的装置,一般包括三轴陀螺仪及三轴加速度计。
本文介绍2D和3D坐标系,以及这些坐标系之间的关系。
深度相机和彩色相机与单独的 2D 坐标系相关联。 [x,y] 坐标以像素为单位,其中,_x_ 的范围为 0 到宽度-1,_y_ 的范围为 0 到高度-1。 宽度和高度取决于所选的深度相机和彩色相机工作模式。像素坐标 [0,0]
对应于图像的左上角像素。
每个相机都与单独的 3D 坐标空间系统相关联。3D 坐标系中的点以指标 [X,Y,Z] 坐标三元组的形式表示,单位为毫米。原点 [0,0,0]
位于相机焦点处。
相机的数据流的二维和三维坐标系之间的关系是由其内在的相机参数描述的。每种设备的都不同,图像可以是任意大小的–宽度和高度字段描述图像中行和列的数目。基本描述如下: 1、图像的视场分别可以改变fx和fy字段描述图像的焦距,是像素宽度和高度的倍数,图像的像素不一定是正方形的,fx和fy允许不同(虽然它们通常是相近的)。 2、描述了主点(投影中心)的像素坐标$$u_0,v_0$$。
在一般情况下,不同相机的数据流的三维坐标系是不同的。例如,由一个或多个红外相机产生的深度数据流,而彩色流则由单独的彩色相机提供。不同数据流的三维坐标系之间的关系用它们的外部参数来描述。基本的 描述如下: 1、相机可能位于不同的位置,但固定在同一物理装置上。位移字段描述相机物理位置之间的三维位移转换 [x,y,z],以米为单位。 2、相机可能有不同的方向,但固定在同一物理装置上。旋转字段包含一个3x3正交旋转矩阵,描述相机之间的物理方向。
透镜的畸变主要分为径向畸变和切向畸变。 径向畸变:是由于透镜形状的制造工艺导致,且越向透镜边缘移动径向畸变越严重,实际情况中我们常用r=0处的泰勒级数展开的前几项来近似描述径向畸变 切向畸变:是由于透镜和CMOS或者CCD的安装位置误差导致,切向畸变需要两个额外的畸变参数来描述。 径向畸变后和切向畸变后的归一化坐标,整理后共需要5个畸变参数$$(k_1, k_2, k_3, p_1, p_2)$$。
从深度图像生成的点云是深度流的三维坐标系中的一组点。也可以从深度和彩色创建点云和相应的纹理映射点云。
通常在处理彩色和深度图像时,需要将每个像素从一个图像映射到另一个图像。要做到图像对齐,就生成一组具有相同分辨率的帧,并且经过处理达到可以简单地映射像素。 我们的对齐方式分为硬件对齐和软件对齐,一般而言,硬件对齐性能上会高于软件对齐。
不同的数据流,因为数据采集不同步、系统处理等原因,会造成数据帧不同步。通过帧数据的时间戳及相应的数据处理,可以尽可能保证两类不同的数据之间的时间差值在一定可控范围,这就是帧同步功能。但需要注意的是,系统往往无法保证严格的帧同步,即两帧之间的时间差值为0。
我们已经完成了 OpenNI2 SDK 的安装过程,并熟悉了一些基本的操作,现在让我们将视线转移 到SDK的四个核心概念 - OpenNI、Device、VideoStream和VideoStreamRef。了解这些概念对于我们后期的开 发和应用有着至关重要的意义。此外,深入理解这四个概念对于后期深入研发以及快速上手未来 可能发布的SDK新功能都会有极大的帮助。
OpenNI 类是API的静态入口,每一个OpenNI2.0的应用程序都需要使用这个类来初始化SDK以及驱动,以便可以创建合法的设备对象。OpenNI类还定义了一个监听器类以及相应的事件,使得当发生设备连接,设备连接断开及设备配置改变时,应用程序能得到事件通知。另外,OpenNI类提供了一个函数用来获取OpenNI的版本信息,提供了一个函数用来等待从列表中任何一个流产生的数据帧。
Device类是对一个特定设备的抽象,特定的设备或者是一个硬件设备,或者是从一个硬件设备记录下来的文件设备。该类提供了连接一个设备,以及获取设备的配置信息和设备支持的流的种类的能力。该类提供了方法来查询和修改设备的配置参数,包括启动深度和彩色流以及帧同步等。当创建和初始化VideoStream类时会使用Device类-为了调用VideoStream.create()功能,我们需要一个Device对象的指针来作为VideoStream.create()函数的其中一个参数,对于应用开发者来说,将Device用来创建及初始化VideoStream是一个最基本的使用Device类的场景。在创建设备对象之前,OpenNI::initialize()函数必须已经被调用,使得API能够获得系统中的设备驱动。
视频流是来自特定数据源的帧的顺序流。想象一下一卷老式电影胶片,其中,视频将作为单个图像快照依次记录在长条胶片上。每个图像快照便是一帧,您可以将整部影片想象成一个流,而流与电影的区别在于流不一定有确切的终点。
VideoStream 对象封装了设备上的一个单独的视频流,VideoStream 对象创建之后,可以用来启动设备上的数据流和从设备上读取数据帧。VideoStream类是OpenNI中获取数据的核心, VideoStream类提供了手动以循环方式读取数据的能力以及提供了以事件驱动方式获取数据的事件类及监听器类的定义。
除了获取数据帧的接口,VideoStream类提供了一系列函数用来获取一个VideoStream对象的信息,比如视场、支持的视频模式以及支持的最大及最小像素值。除了获取数据,VideoStream对象还用来配置一个指定流的属性,特别地,可以用来控制裁剪、镜像和视频模式。
创建流时,我们需要 一个指向合法的已初始化设备(该设备需支持待创建的流类型)的指针作为参数。同一个传感器上可以创建多个视频流,这对当一个应用的多个模块都需要单独读取帧数据时很有用。
VideoFrameRef 类是对一个视频帧及其元始数据的抽象。视频帧是一个特定的视频流在某个时间的输出。输出的数据中包含单个帧(Color、IR或者Depth)以及对应的元数据。
一个VideoFrameRef类的对象并不是真正持有帧中的数据,而只是帧的引用。这个引用可以通过销毁VideoFrameRef对象或者通过调用release()方法来释放。当帧的最后一个引用释放后,帧中的数据才会被真正的释放。
最常用的获取VideoFrameRef对象的方法是调用VideoStream::readFrame()。
VideoFrameRef对象引用的数据以像素数组格式存储。每个像素的类型都与指定的像素格式保持一致。