ubuntu环境下从深度相机Kinect V1获取图像

前言


首先,讲个故事:
PrimeSense公司成立于2005年,Kinect深度相机中的深度感知技术是PrimeSense这个公司提供的。
2010年PrimeSense公司发布了自己的开源驱动和运动跟踪的中间软件,叫做NITE,后来还和华硕公司一起合作,说要在2012年发布一个和Kinect类似的设备叫做,Xtion
而有一个组织叫OpenNI,他们搞了个同名软件包OpenNI,用来对一些自然交互设备进行认证并且改善交互性。OpenNI的幕后赞助大佬就有一个是PrimeSense。不过在2013年,苹果公司确定收购了PrimeSense公司。
不知是否为收购导致的原因还是一直就存在的问题,反正ubuntu环境下openni对Kinect的支持有点问题。

PrimeSense:

PrimeSense, who was founding member of OpenNI, shutdown the original OpenNI project when it was acquired by Apple on November 24, 2013; since then Occipital and other former partners of PrimeSense are still keeping a forked version of OpenNI 2 (OpenNI version 2) active as an open source software, primary for their own Structure SDK (Software Development Kit) which is used by their Structure Product.

NITE:

In December 2010, PrimeSense, whose depth sensing reference design Kinect is based on, released their own open source drivers along with motion tracking middleware called NITE.
PrimeSense later announced that it had teamed up with Asus to develop a PC-compatible device similar to Kinect, which will be called Wavi Xtion and is scheduled for release in the second quarter of 2012.

OpenNI(Open Natural Interaction)

OpenNI is an industry-led non-profit organization and open source software project focused on certifying and improving interoperability of natural user interfaces and organic user interfaces for Natural Interaction (NI) devices, applications that use those devices and middleware that facilitates access and use of such devices
OpenNI is primarly developed by PrimeSence, which is the company behind Kinect’s depth sensor’s technology.

既然存在一些问题,这怎么能忍,开源者的人是伟大的。
出现了Openni+SensorKinect+Nite的方案。

SensorKinect is an OpenNI module that allows it to talk with the Kinect. Basically, OpenNI and NITE are middleware and SensorKinect is the hardware driver.

也出现了Openni2+libfreenect的方案。
OpenKinect是一个开源社区,主要针对于那些对Kienct设备感兴趣利用它来做一些开发的人。

OpenKinect is a community of people, not a library. The OpenKinect community releases the libfreenect Kinect driver.

那么这个社区搞的开源驱动呢,就叫做libfreenect(随着Kinect V2的出现,相应地也开发了libfreenect2)

libfreenect (Apache 2.0 or GPLv2) derives from the initial, reverse-engineered/hacked Kinect driver

总结一下:
在windows系统中,可以安装Kinect for Windows SDK来进行开发,也可以安装其他开源驱动。
在ubuntu中,通过kinect获取深度图像和彩色图像有以下几种方案(如果有其他方案,欢迎补充):
本文默认在不安装ROS的情况下(其实是我因为还不会,哈哈):
1.安装Openni+SensorKinect+Nite来获取图像;
2.安装Openni2+libfreenect来获取图像;
3.只通过libfreenect来获取图像(这个不太清楚,貌似是只用libfreenect的API)
由于我要用到Openni2,所以本文暂时只针对第二种方式进行介绍。(编了这么一大串,终于要进入正题啦!!)

安装驱动


Openni2的安装

我这里是通过opennni组织的官网下载的。将安装包解压后,进入驱动目录,运行安装脚本:

sudo ./install.sh

然后会生成一个环境变量的配置文件,方便起见,可以把它写入系统环境变量的文件:

cat OpenNIDevEnvironment >> ~/.bashrc
source ~/.bashrc

openni下载网址

libfreenect的安装

然后在github上去下载libfreenect的包,按照文档的说明进行编译,如下图:
ubuntu环境下从深度相机Kinect V1获取图像_第1张图片
编译完了以后,按照提示,把相应位置的库文件拷贝到openni2的相应目录下。

获取图像


用Cmake来管理工程,在CMakeLists.txt中引入Openni2就可以了。就不需要去管libfreenect了。
下面给出一段代码,参考自以下博客:
谈谈OpenNI 2与OpenCV结合的第一个程序

// YeOpenNI2SimpleUsingOpenCV.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
#include "OpenNI.h"

// 载入OpenCV头文件
#include "opencv2/opencv.hpp"
#include 
#include 
#include 

using namespace std;
using namespace openni;
using namespace cv;

int main( int argc, char** argv )
{
    // 初始化OpenNI环境
    OpenNI::initialize();

    // 声明并打开Device设备,我用的是Kinect。
    Device devAnyDevice;
    devAnyDevice.open(ANY_DEVICE );

    // 创建深度数据流
    VideoStream streamDepth;
    streamDepth.create( devAnyDevice, SENSOR_DEPTH );

    // 创建彩色图像数据流
    VideoStream streamColor;
    streamColor.create( devAnyDevice, SENSOR_COLOR );

    // 设置深度图像视频模式
    VideoMode mModeDepth;
    // 分辨率大小
    mModeDepth.setResolution( 640, 480 );
    // 每秒30帧
    mModeDepth.setFps( 30 );
    // 像素格式
    mModeDepth.setPixelFormat( PIXEL_FORMAT_DEPTH_1_MM );

    streamDepth.setVideoMode( mModeDepth);
    
    // 同样的设置彩色图像视频模式
    VideoMode mModeColor;
    mModeColor.setResolution( 640, 480 );
    mModeColor.setFps( 30 );
    mModeColor.setPixelFormat( PIXEL_FORMAT_RGB888 );

    streamColor.setVideoMode( mModeColor);

    // 图像模式注册
    if( devAnyDevice.isImageRegistrationModeSupported(
        IMAGE_REGISTRATION_DEPTH_TO_COLOR ) )
    {
        devAnyDevice.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR );
    }
        
    // 打开深度和图像数据流
    streamDepth.start();
    streamColor.start();

    // 创建OpenCV图像窗口
    namedWindow( "Depth Image",  CV_WINDOW_AUTOSIZE );
    namedWindow( "Color Image",  CV_WINDOW_AUTOSIZE );

    // 获得最大深度值
    int iMaxDepth = streamDepth.getMaxPixelValue();

    // 循环读取数据流信息并保存在VideoFrameRef中
    VideoFrameRef  frameDepth;
    VideoFrameRef  frameColor;

    while( true )
    {
        // 读取数据流
        streamDepth.readFrame( &frameDepth );
        streamColor.readFrame( &frameColor );

        
        // 将深度数据转换成OpenCV格式
        const cv::Mat mImageDepth( frameDepth.getHeight(), frameDepth.getWidth(), CV_16UC1, (void*)frameDepth.getData());
        // 为了让深度图像显示的更加明显一些,将CV_16UC1 ==> CV_8U格式
        cv::Mat mScaledDepth;
        mImageDepth.convertTo( mScaledDepth, CV_8U, 255.0 / iMaxDepth );
        // 显示出深度图像
        cv::imshow( "Depth Image", mScaledDepth );

        // 同样的将彩色图像数据转化成OpenCV格式
        const cv::Mat mImageRGB(frameColor.getHeight(), frameColor.getWidth(), CV_8UC3, (void*)frameColor.getData());
        // 首先将RGB格式转换为BGR格式
        cv::Mat cImageBGR;
        cv::cvtColor( mImageRGB, cImageBGR, CV_RGB2BGR );
        // 然后显示彩色图像
        cv::imshow( "Color Image", cImageBGR );

        // 终止快捷键
        if( cv::waitKey(1) == 'q')
            break;
    }

    // 关闭数据流
    streamDepth.destroy();
    streamColor.destroy();

    // 关闭设备
    devAnyDevice.close();

    // 最后关闭OpenNI
    openni::OpenNI::shutdown();

    return 0;
}

参考链接

stackoverflow: what-is-sensorkinect
wiki: OpenNI
wiki: PrimeSense
github: SensorKinect
openkinect.org
stackoverflow: what-is-the-difference-between-openni-and-openkinect
stackoverflow: libfreenect-vs-openni
Ubuntu下配置Openni2+libFreenect

你可能感兴趣的:(ubuntu环境下从深度相机Kinect V1获取图像)