******* HighGUI ******* .. highlight:: cpp 使用Kinect传感器 =================== 类 ``VideoCapture`` 支持Kinect传感器。使用 ``VideoCapture`` 里的接口,可以从Kinect获取深度图,RGB图像和其他格式的输出。 为了在OpenCV中使用Kinect,你需要遵循如下主要步骤。 #. 安装OpenNI库 (从此处获取 http://www.openni.org/downloadfiles) 以及 PrimeSensor Module for OpenNI (从此处获取 https://github.com/avin2/SensorKinect )。使用它们的缺省安装目录安装则可。安装目录如下: .. code-block:: text OpenNI: Linux & MacOSX: Libs into: /usr/lib Includes into: /usr/include/ni Windows: Libs into: c:/Program Files/OpenNI/Lib Includes into: c:/Program Files/OpenNI/Include PrimeSensor Module: Linux & MacOSX: Bins into: /usr/bin Windows: Bins into: c:/Program Files/Prime Sense/Sensor/Bin 如果其中一个或者多个被安装到其他目录,你应该修改与之对应的CMake变量 ``OPENNI_LIB_DIR`` , ``OPENNI_INCLUDE_DIR`` 或/和 ``OPENNI_PRIME_SENSOR_MODULE_BIN_DIR`` 。 #. 通过CMake中的 ``WITH_OPENNI`` 标志配置OpenCV的OpenNI支持。无论发现PrimeSensor模块与否(检查CMake log中的 ``OpenNI PrimeSensor Modules`` 状态),如果在安装目录中发现了OpenNI(检查CMake log中的 ``OpenNI`` 状态),OpenCV都将会使用OpenNI编译。没有PrimeSensor模块,OpenCV也可成功地与OpenNI编译,但是 ``VideoCapture`` 对象无法从Kinect传感器中抓取数据。 #. 编译OpenCV。 VideoCapture 可以获取如下Kinect数据: #. 来自深度传感器的数据: * ``OPENNI_DEPTH_MAP`` - 以毫米为单位的深度值 (CV_16UC1) * ``OPENNI_POINT_CLOUD_MAP`` - 以米为单位的XYZ点云 (CV_32FC3) * ``OPENNI_DISPARITY_MAP`` - 以像素为单位的视差 (CV_8UC1) * ``OPENNI_DISPARITY_MAP_32F`` - 以像素为单位的视差 (CV_32FC1) * ``OPENNI_VALID_DEPTH_MASK`` - 有效像素标志 (非遮挡,非影子区等) (CV_8UC1) #. 来自RGB图像传感器的数据: * ``OPENNI_BGR_IMAGE`` - 彩色图像 (CV_8UC3) * ``OPENNI_GRAY_IMAGE`` - 灰度图像 (CV_8UC1) 为了从Kinect获取深度图,请使用 ``VideoCapture::operator >>``, 例如 :: VideoCapture capture( CV_CAP_OPENNI ); for(;;) { Mat depthMap; capture >> depthMap; if( waitKey( 30 ) >= 0 ) break; } 如果获取多个Kinect数据,请使用 ``VideoCapture::grab`` 和 ``VideoCapture::retrieve``, 例如 :: VideoCapture capture(0); // or CV_CAP_OPENNI for(;;) { Mat depthMap; Mat rgbImage capture.grab(); capture.retrieve( depthMap, OPENNI_DEPTH_MAP ); capture.retrieve( bgrImage, OPENNI_BGR_IMAGE ); if( waitKey( 30 ) >= 0 ) break; } 设置或者获取Kinect数据属性,请分别使用 ``VideoCapture::set`` 和 ``VideoCapture::get`` 。例如 :: VideoCapture capture( CV_CAP_OPENNI ); capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ ); cout << "FPS " << capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FPS ) << endl; 既然Kinect有两个数据传感器(图像传感器和深度传感器),因此有两个标志用来设置/获取指定传感器的属性: * CV_CAP_OPENNI_IMAGE_GENERATOR -- 读写图像传感器属性的标志。 * CV_CAP_OPENNI_DEPTH_GENERATOR -- 读写深度传感器属性的标志。此标志为默认值,如果这两个标志都没有设置,则为此标志。 当读写特定传感器属性时,必须用此标志指定传感器。如下属性可透过OpenNI接口支持: * 图像传感器: - ``CV_CAP_PROP_OPENNI_OUTPUT_MODE`` -- 支持两种模式:缺省的 ``CV_CAP_OPENNI_VGA_30HZ`` (图像传感器以30FPS速度返回VGA分辨率的图像) 或者 ``CV_CAP_OPENNI_SXGA_15HZ`` (图像传感器以15FPS速度返回SXGA分辨率的图像);深度传感器一直是VGA分辨率。 * 深度传感器: - ``CV_CAP_PROP_OPENNI_REGISTRATION`` -- 此标志用来校准深度图,通过改变深度传感器的视点到图像传感器,这样两图中同一位置的像素表示同一物体(需将此标志设置为 ``"on"``); 或者设置深度传感器的视点为其本来的视点(需将此标志设置为 ``"off"``). 下面的属性仅可读取: - ``CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH`` -- Kinect支持的最大距离,以毫米为单位。 - ``CV_CAP_PROP_OPENNI_BASELINE`` -- Baseline值,以毫米为单位。 - ``CV_CAP_PROP_OPENNI_FOCAL_LENGTH`` -- 焦距,以像素为单位。 - ``CV_CAP_PROP_FRAME_WIDTH`` -- 帧的宽度,以像素为单位。 - ``CV_CAP_PROP_FRAME_HEIGHT`` -- 帧的高度,以像素为单位。 - ``CV_CAP_PROP_FPS`` -- 帧率,以FPS为单位。 * 一些"generator type + property"被定以为一个标志: - ``CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE = CV_CAP_OPENNI_IMAGE_GENERATOR + CV_CAP_PROP_OPENNI_OUTPUT_MODE`` - ``CV_CAP_OPENNI_DEPTH_GENERATOR_BASELINE = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_BASELINE`` - ``CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_FOCAL_LENGTH`` - ``CV_CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION_ON = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_REGISTRATION_ON`` 更多信息,请参考 ``opencv/samples/cpp`` 目录中的Kinect例子 ``kinect_maps.cpp`` 。 翻译 ====================== 于仕琪 http://www.opencv.org.cn