最近入手NvidiaTegra 1 开发板,ARM架构的,做室内三维重建用。今天就讲讲的PCL 1.8+ OPENCV3.1 + OPENNI2.0在ubuntu14.04 上的安装与编译。
更新ubuntu的armhf源,修改source.list,中科大的快!
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty main restricted universe multiverse deb http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty-security main restricted universe multiverse deb http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty-updates main restricted universe multiverse deb http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty-proposed main restricted universe multiverse deb http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty-backports main restricted universe multiverse deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty main restricted universe multiverse deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty-security main restricted universe multiverse deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty-updates main restricted universe multiverse deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty-proposed main restricted universe multiverse deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty-backports main restricted universe multiverse
一、 Opencv
这个网上有很多教程,
1. 安装依赖包和预备环境
$sudo apt-get install build-essential $sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev $sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
2.从官网下载opencv3.1源码,并解压
3.创建编译目录,编译
$cd ~/opencv-3.1.0 $mkdir release $cd release $cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local .. $make $sudo make install
4.测试opencv
$mkdir ~/opencv-lena $cd ~/opencv-lena $gedit DisplayImage.cpp
#include <stdio.h> #include <opencv2/opencv.hpp> using namespace cv; int main(int argc, char** argv ) { if ( argc != 2 ) { printf("usage: DisplayImage.out <Image_Path>\n"); return -1; } Mat image; image = imread( argv[1], 1 ); if ( !image.data ) { printf("No image data \n"); return -1; } namedWindow("Display Image", WINDOW_AUTOSIZE ); imshow("Display Image", image); waitKey(0); return 0; }
创建cmakelist编译文件
cmake_minimum_required(VERSION 2.8) project( DisplayImage ) find_package( OpenCV REQUIRED ) add_executable( DisplayImage DisplayImage.cpp ) target_link_libraries( DisplayImage ${OpenCV_LIBS} )
执行:
$cd ~/opencv-lena $cmake . $make
$./DisplayImage lena.jpg
至此opencv配置完毕
二、openni2.0
以下内容是我在youtube上看到的视频:
https://www.youtube.com/watch?v=Bn9WqbYtNBw
1.安装 OpenNI2依赖项
$sudo apt-get install -y g++ python libusb-1.0-0-dev freeglut3-dev doxygen graphviz $sudo apt-get install libudev-dev
2.从github将openni2源码clone下来
$git clone https://github.com/occipital/OpenNI2.git $cd OpenNI2
3.修改两处配置Platform.Arm和CommonCppMakefile,适用于arm设备
$gedit ThirdParty/PSCommon/BuildSystem/Platform.Arm
Change:
CFLAGS+= -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp#-mcpu=cortex-a8
to:
CFLAGS+= -march=armv7-a -mtune=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard
$gedit ThirdParty/PSCommon/BuildSystem/CommonCppMakefile
---OpenNI2-2.2.0.30/ThirdParty/PSCommon/BuildSystem/CommonCppMakefile.old2014-03-28 19:09:11.572263107 -0700
+++OpenNI2-2.2.0.30/ThirdParty/PSCommon/BuildSystem/CommonCppMakefile 2014-03-2819:09:55.600261937 -0700
@@-95,6 +95,9 @@
OUTPUT_NAME= $(EXE_NAME)
# Wewant the executables to look for the .so‘s locally first:
LDFLAGS+= -Wl,-rpath ./
+ifneq ("$(OSTYPE)","Darwin")
+LDFLAGS += -lpthread
+endif
OUTPUT_COMMAND= $(CXX) -o $(OUTPUT_FILE) $(OBJ_FILES) $(LDFLAGS)
endif
ifneq "$(SLIB_NAME)" ""
4.修改makefile,增加sample,即在makefile文件末尾添加:
core_samples: $(CORE_SAMPLES) tools: $(ALL_TOOLS)
5.编译
$make $make core_samples # this probably isn‘t necessary, they should already be built $GLUT_SUPPORTED=1 make tools#GLUT_SUPPORTED tells the make to compile NiViewer for OpenGL
6.安装libfreenect,否则无法驱动primesensor
安装依赖项
$sudo apt-get install cmake freeglut3-dev pkg-config build-essential libxmu-dev libxi-dev libusb-1.0-0-dev –y
下载源码并编译
$ git clone git://github.com/OpenKinect/libfreenect.git $ cd libfreenect $ mkdir build $ cd build $ cmake .. $ make $ sudo make install # Build the OpenNI2 driver $ cmake .. -DBUILD_OPENNI2_DRIVER=ON $ make
将libfreenect的so拷贝到OpenNI的驱动文件夹下
$ Repository=../../Bin/Arm-Release/OpenNI2/Drivers $ cp -L lib/OpenNI2-FreenectDriver/libFreenectDriver* ${Repository}
设置使用传感器的权限
$ sudo usermod -a -G video Ubuntu
7.回到openni2目录,将头文件和so文件拷贝到/usr目录下
$ sudo cp -r Include /usr/include/openni2 $ sudo cp -r Bin/Arm-Release/OpenNI2 /usr/lib/ $ sudo cp Bin/Arm-Release/libOpenNI2.* /usr/lib/
8.创建packageconfig文件
# this will enable ubuntu to find the location of the drivers, libraries and include files. $ sudo gedit /usr/lib/pkgconfig/libopenni2.pc and fill it with this: 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
检验:
# To make sure it is correctly found, run $ pkg-config --modversion libopenni2 # which should give the same version as defined in the file above (2.2.0.0)
最后一步:
# Linux has used the udev system to handle devices such as USB connected peripherals. $ cd Packaging/Linux $ sudo cp primesense-usb.rules /etc/udev/rules.d/557-primesense-usb.rules
翻译的如果卡不懂和其他注意事项,
请直接看:http://jetsonhacks.com/2014/08/28/building-openni2-structure-sensor/
运行结果:
三、PCL安装
参考:
http://larrylisky.com/2014/03/03/installing-pcl-on-ubuntu/
安装依赖环境
sudo apt-get install g++ sudo apt-get install cmake cmake-gui sudo apt-get install doxygen sudo apt-get install mpi-default-dev openmpi-bin openmpi-common sudo apt-get install libflann1 libflann-dev sudo apt-get install libeigen3-dev sudo apt-get install libboost-all-dev sudo apt-get install libvtk5.8-qt4 libvtk5.8 libvtk5-dev sudo apt-get install libqhull* sudo apt-get install libusb-dev sudo apt-get install libgtest-dev sudo apt-get install git-core freeglut3-dev pkg-config sudo apt-get install build-essential libxmu-dev libxi-dev sudo apt-get install libusb-1.0-0-dev graphviz mono-complete sudo apt-get install qt-sdk openjdk-7-jdk openjdk-7-jre sudo apt-get install phonon-backend-gstreamer sudo apt-get install phonon-backend-vlc
从github上下载pcl最新版本并编译
$git clone https://github.com/PointCloudLibrary/pcl.git pcl-trunk ln -s pcl-trunk pcl(我是直接下载了压缩包,解压的,不然太慢了) $mkdir release $cd release $cmake -DCMAKE_BUILD_TYPE=None -DBUILD_GPU=ON -DBUILD_apps=ON -DBUILD_examples=ON .. $make $sudo make install
至此完成安装,但是是VTK有问题的,留着下次解决
四、最后再给出三个库同时使用的情形:
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})
c++文件:
#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;*/ } } }
运行结果:
键盘输入c抓取数据,按q退出