您的位置:首页 > 运维架构

ubuntu14.04安装OpenNI2+驱动XTion PRO Live

2016-11-30 00:22 483 查看
这篇博客将为大家介绍如何在ubuntu14.04下安装OpenNI2,以及驱动华硕的深度摄像头XTion PRO Live。

经过几天搜索资料,发现网上关于安装OpenNI2资料还是较少而且很乱,今天经过测试,终于成功读取XTion摄像头的数据并将其生成点云。

好了,废话少说,正式进入主题

事先准备:

系统:Ubuntu 14.04

摄像头:华硕XTion Pro Live

一、安装OPenNI2

1、安装依赖项

sudo apt-get install -y g++ git python libusb-1.0-0-dev libudev-dev freeglut3-dev doxygen graphviz openjdk-6-jdk


2、创建一个新的文件夹,用于存放从github下载下来的OpenNI2,并移到此文件夹下

mkdir ~/openni2
cd ~/openni2


3、从GitHub下载OpenNI2的代码

git clone https://github.com/occipital/OpenNI2.git[/code] 
4、进入OpenNI2文件夹

cd OpenNI2


5、运行下面代码

find . -iname platform.arm


终端会输出以下信息:

./ThirdParty/PSCommon/BuildSystem/Platform.Arm

6、运行gedit,打开Platform.Arm文件进行修改

gedit ./ThirdParty/PSCommon/BuildSystem/Platform.Arm


找到:

CFLAGS += -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard

修改为:

CFLAGS += -march=armv7-a -mtune=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard

如下图所示:



7、打开gedit,修改CommonCppMakefile文件

gedit ThirdParty/PSCommon/BuildSystem/CommonCppMakefile


找到这两行:

LDFLAGS += -Wl,-rpath ./

OUTPUT_COMMAND = (CXX)−o(OUTPUT_FILE) (OBJFILES)(LDFLAGS)

在这两行代码中间加入以下代码:

ifneq (“$(OSTYPE)”,”Darwin”)
LDFLAGS += -lpthread
endif


如下图所示:



保存退出。

8、添加例程以检查安装是否正确

gedit Makefile


在文件末尾添加:

core_samples: $(CORE_SAMPLES)

如下图:



保存退出。

9、开始编译

make
make core_samples
GLUT_SUPPORTED=1 make tools


二、OpenNI2测试

1、进入例程所在文件夹

cd ~/openni2/OpenNI2/Bin/x64-Release


2、连接Xtion Pro Live到你的电脑

3、测试例程“SimpleRead”:

./SimpleRead


不出意外,在这里你应该能够看到终端很多数据在更新,当你移动摄像头时,数据会发生 明显变化

如下图所示:



4、测试 例程“NiViewer”:

./NiViewer


这是你应该能够看到深度图了

如下图所示:



三、正式安装OpenNI2

1、进入Packaging文件夹

cd ~/openni2/OpenNI2/Packaging/Linux


2、运行安装脚本

sudo sh install.sh


3、将“lib”文件和“include”文件复制到系统路径下

cd ~/openni2/OpenNI2
sudo cp -r Include /usr/include/openni2
sudo cp -r Bin/x64-Release/OpenNI2 /usr/lib/
sudo cp Bin/x64-Release/libOpenNI2.* /usr/lib/


4、更新 library cache:

sudo ldconfig


5、设置传感器权限

sudo usermod -a -G video Ubuntu


注意,Ubuntu为你的用户名

6、创建一个包配置文件

sudo gedit /usr/lib/pkgconfig/libopenni2.pc


7、用一下代码覆盖

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/openni2

Name: OpenNI2
Description: A general purpose driver for all OpenNI cameras.
Version: 2.2.0.0
Cflags: -I${includedir}
Libs: -L${libdir} -lOpenNI2 -L${libdir}/OpenNI2/Drivers -lDummyDevice -lOniFile -lPS1080.so


8、确保其能被正确找到,运行:

pkg-config --modversion libopenni2


此时,终端会有2.2.0.0回复

如下图所示:



至此,OpenNI2已经安装好了,并可以驱动Xtion了

四、测试

那么接下来就是测试一下,看看能否读取Xtion摄像头,并将其生成点云(前提有安装Opencv-2.4.9和PCL1.7)

1、新建一个test文件夹并移至该文件夹

mkdir ~/test
cd ~/test


2、再新建一个build文件夹,用于存放编译文件

mkdir build


3、在test文件夹新建CMakeLists.txt

# This CmakeLists include both OpenNI and OpenCV Libraries
cmake_minimum_required(VERSION 2.8)
project( TestOpenNI )

# OpenCV
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
MESSAGE(STATUS "The Opencv's include directory is:" ${OpenCV_INCLUDE_DIRS})

#OpenNI
FIND_PATH(OpenNI2_INCLUDE_DIRS OpenNI.h HINTS  $ENV{OPENNI2_INCLUDE} PATH_SUFFIXES openni2)
FIND_LIBRARY(OpenNI2_LIBRARY NAMES OpenNI2 HINTS  $ENV{OPENNI2_LIB} $ENV{OPENNI2_REDIST})
include_directories( ${OpenNI2_INCLUDE_DIRS} )

IF (OpenNI2_INCLUDE_DIRS AND OpenNI2_LIBRARY)
SET(OpenNI2_FOUND TRUE)
ENDIF (OpenNI2_INCLUDE_DIRS AND OpenNI2_LIBRARY)

IF (OpenNI2_FOUND)
# show which OpenNI2 was found only if not quiet
SET(OpenNI2_LIBRARIES ${OpenNI2_LIBRARY})
MESSAGE(STATUS "Found OpenNI2: ${OpenNI2_LIBRARIES}")
ELSE (OpenNI2_FOUND)
# fatal error if OpenNI2 is required but not found
IF (OpenNI2_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find OpenNI2. Environment variables OPENNI2_INCLUDE (directory containing OpenNI.h) and OPENNI2_LIB (directory containing OpenNI2 library) could bet set.")
ENDIF (OpenNI2_FIND_REQUIRED)
ENDIF (OpenNI2_FOUND)

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
#set (OPENNI_H /usr/include/openni2/OpenNI.h)
# ---------------------------------------------------------

#PCL
find_package(PCL 1.8 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(TestOpenNI test.cpp)
target_link_libraries(TestOpenNI ${OpenNI2_LIBRARIES} ${OpenCV_LIBS} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES})


4、在build文件夹下新建TestOpenNI.cpp

#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
// 标准库头文件
#include <iostream>
#include <string>
#include <vector>
// OpenCV头文件
#include <opencv2/photo.hpp>
#include <opencv2/highgui.hpp>
// OpenNI头文件
#include <OpenNI.h>
typedef unsigned char uint8_t;
// namespace
using namespace std;
using namespace openni;
using namespace cv;
using namespace pcl;

void CheckOpenNIError( Status result, string status )
{
if( result != STATUS_OK )
cerr << status << " Error: " << OpenNI::getExtendedError() << endl;
}

int main( int argc, char **argv )
{
Status result = STATUS_OK;
int i,j;
float x=0.0,y=0.0,z=0.0,xx=0.0;
//IplImage *test,*test2;
IplImage *test2;
char filename[20] = {0};

//point cloud
PointCloud<PointXYZ> cloud;
PointCloud<PointXYZRGB> color_cloud;

//opencv image
Mat cvBGRImg;
Mat cvDepthImg;

//OpenNI2 image
VideoFrameRef oniDepthImg;
VideoFrameRef oniColorImg;

namedWindow("depth");
namedWindow("image");

char key=0;

// 初始化OpenNI
result = OpenNI::initialize();
CheckOpenNIError( result, "initialize context" );

// open device
Device device;
result = device.open( openni::ANY_DEVICE );
CheckOpenNIError( result, "open device" );

// create depth stream
VideoStream oniDepthStream;
result = oniDepthStream.create( device, openni::SENSOR_DEPTH );
CheckOpenNIError( result, "create depth stream" );

// set depth video mode
VideoMode modeDepth;
modeDepth.setResolution( 640, 480 );
modeDepth.setFps( 30 );
modeDepth.setPixelFormat( PIXEL_FORMAT_DEPTH_1_MM );
oniDepthStream.setVideoMode(modeDepth);
// start depth stream
result = oniDepthStream.start();
CheckOpenNIError( result, "start depth stream" );

// create color stream
VideoStream oniColorStream;
result = oniColorStream.create( device, openni::SENSOR_COLOR );
CheckOpenNIError( result, "create color stream" );
// set color video mode
VideoMode modeColor;
modeColor.setResolution( 640, 480 );
modeColor.setFps( 30 );
modeColor.setPixelFormat( PIXEL_FORMAT_RGB888 );
oniColorStream.setVideoMode( modeColor);
// start color stream
result = oniColorStream.start();
CheckOpenNIError( result, "start color stream" );

int count = 0;
while(true)
{
// read frame
if( oniColorStream.readFrame( &oniColorImg ) == STATUS_OK )
{
// convert data into OpenCV type
Mat cvRGBImg( oniColorImg.getHeight(), oniColorImg.getWidth(), CV_8UC3, (void*)oniColorImg.getData() );
cvtColor( cvRGBImg, cvBGRImg, CV_RGB2BGR );
imshow( "image", cvBGRImg );
}

if( oniDepthStream.readFrame( &oniDepthImg ) == STATUS_OK )
{
Mat cvRawImg16U( oniDepthImg.getHeight(), oniDepthImg.getWidth(), CV_16UC1, (void*)oniDepthImg.getData() );
cvRawImg16U.convertTo( cvDepthImg, CV_8U, 255.0/(oniDepthStream.getMaxPixelValue()));
imshow( "depth", cvDepthImg );
}

char input = waitKey(1);
// quit
if( input == 'q' )
break;
// capture  depth and color data
if( input == 'c' )
{
//get data
DepthPixel *pDepth = (DepthPixel*)oniDepthImg.getData();
//create point cloud
cloud.width = oniDepthImg.getWidth();
cloud.height = oniDepthImg.getHeight();
cloud.is_dense = false;
cloud.points.resize(cloud.width * cloud.height);
color_cloud.width = oniDepthImg.getWidth();
color_cloud.height = oniDepthImg.getHeight();
color_cloud.is_dense = false;
color_cloud.points.resize(color_cloud.width * color_cloud.height);

//test = cvCreateImage(cvSize(cloud.width,cloud.height),IPL_DEPTH_8U,3);
IplImage temp11 = (IplImage)cvBGRImg;
//test2 = &IplImage(cvBGRImg);
test2 = &temp11;

for(i=0;i<oniDepthImg.getHeight();i++)
{
for(j=0;j<oniDepthImg.getWidth();j++)
{
float k = i;
float m = j;
xx = pDepth[i*oniDepthImg.getWidth()+j];
CoordinateConverter::convertDepthToWorld (oniDepthStream,m,k,xx,&x,&y,&z);
cloud[i*cloud.width+j].x = x/1000;
cloud[i*cloud.width+j].y = y/1000;
cloud[i*cloud.width+j].z = z/1000;

color_cloud[i*cloud.width+j].x = x/1000;
color_cloud[i*cloud.width+j].y = y/1000;
color_cloud[i*cloud.width+j].z = z/1000;
color_cloud[i*cloud.width+j].b = (uint8_t)test2->imageData[i*test2->widthStep+j*3+0];
color_cloud[i*cloud.width+j].g = (uint8_t)test2->imageData[i*test2->widthStep+j*3+1];
color_cloud[i*cloud.width+j].r = (uint8_t)test2->imageData[i*test2->widthStep+j*3+2];
/* test->imageData[i*test->widthStep+j*3+0] = test2->imageData[i*test2->widthStep+j*3+0];
test->imageData[i*test->widthStep+j*3+1] = test2->imageData[i*test2->widthStep+j*3+1];
test->imageData[i*test->widthStep+j*3+2] = test2->imageData[i*test2->widthStep+j*3+2];*/
}
}

//cvSaveImage("test.jpg",test);
//pcl::io::savePLYFileBinary("test_plyc.ply",cloud);
cout<<"the "<<count<<" is saved"<<endl;
sprintf(filename,"./data/%d.pcd",count);
pcl::io::savePCDFileBinaryCompressed(filename,cloud);
cerr<<"Saved "<<cloud.points.size()<<" data points to xyz pcd."<<endl;
sprintf(filename,"./data/color_%d.pcd",count);
pcl::io::savePCDFileBinaryCompressed(filename,color_cloud);
cerr<<"Saved "<<color_cloud.points.size()<<" data points to xyzrgb pcd."<<endl;
sprintf(filename,"./data/color_%d.jpg",count);
imwrite(filename,cvBGRImg);
sprintf(filename,"./data/depth_%d.jpg",count++);
imwrite(filename,cvDepthImg);
/*for(size_t i=0;i<cloud.points.size();++i)
cerr<<"    "<<cloud.points[i].x<<" "<<cloud.points[i].y<<" "<<cloud.points[i].z<<endl;*/
}
}
}


5、在build的文件夹下进行编译

cmake ..
make


不出问题在build的文件夹下就能产生可执行文件TestOpenNI

6、运行可执行文件TestOpenNI

如下图:



主要参考blog:

http://myzharbot.robot-home.it/blog/software/configuration-nvidia-jetson-tk1/asus-xtion-pro-live-openni2-compilation-install-instructions/

http://blog.csdn.net/u013294888/article/details/51244736
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: