当前位置: 代码迷 >> 综合 >> OpenNi2+PCL显示彩色点云
  详细解决方案

OpenNi2+PCL显示彩色点云

热度:56   发布时间:2023-12-08 18:13:47.0

###一、openni2使用摄像头获取图像步骤:

1.openni初始化
2.openni打开设备
3.创建数据流并设置数据流模式

二、转化点云步骤

1.使用openni从数据流读取一帧图像
2.使用openni从图像读取像素数据
3.处理数据,将结果存入点云

三、示例代码

#include <iostream> 
#include <OpenNI.h>
#include <pcl/common/common_headers.h>       // for pcl::PointCloud
#include <pcl/visualization/pcl_visualizer.h>openni::Device mDevice;
openni::VideoStream mColorStream;
openni::VideoStream mDepthStream;bool init(){// Initial OpenNIif(openni::OpenNI::initialize() != openni::STATUS_OK){std::cerr << "OpenNI Initial Error: "  << openni::OpenNI::getExtendedError() << std::endl;return false;}// Open Deviceif(mDevice.open(openni::ANY_DEVICE) != openni::STATUS_OK) {std::cerr << "Can't Open Device: "  << openni::OpenNI::getExtendedError() << std::endl;return false;}return true;
}bool createColorStream() {if(mDevice.hasSensor(openni::SENSOR_COLOR)) {if(mColorStream.create(mDevice, openni::SENSOR_COLOR) == openni::STATUS_OK) {// set video modeopenni::VideoMode mMode;mMode.setResolution(640, 480);mMode.setFps(30);mMode.setPixelFormat( openni::PIXEL_FORMAT_RGB888 );if(mColorStream.setVideoMode(mMode) != openni::STATUS_OK) {std::cout << "Can't apply VideoMode: "  << openni::OpenNI::getExtendedError() << std::endl;return false;}} else {std::cerr << "Can't create color stream on device: " << openni::OpenNI::getExtendedError() << std::endl;return false;}// start color streammColorStream.start();return true;}return false;
}bool createDepthStream(){if(mDevice.hasSensor(openni::SENSOR_DEPTH)) {if(mDepthStream.create(mDevice, openni::SENSOR_DEPTH) == openni::STATUS_OK) {// set video modeopenni::VideoMode mMode;mMode.setResolution(640,480);mMode.setFps(30);mMode.setPixelFormat(openni::PIXEL_FORMAT_DEPTH_1_MM);if(mDepthStream.setVideoMode(mMode) != openni::STATUS_OK) {std::cout << "Can't apply VideoMode to depth stream: " << openni::OpenNI::getExtendedError() << std::endl;return false;}} else {std::cerr << "Can't create depth stream on device: " << openni::OpenNI::getExtendedError() << std::endl;return false;}// start depth streammDepthStream.start();// image registrationif( mDevice.isImageRegistrationModeSupported(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR) )mDevice.setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR);elsestd::cerr << "Don't support registration" << std::endl;return true;} else {std::cerr << "ERROR: This device does not have depth sensor" << std::endl;return false;}
}//openni图像流转化成点云
bool getCloudXYZCoordinate(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_XYZRGB)  {openni::VideoFrameRef  colorFrame;mColorStream.readFrame(&colorFrame);openni::RGB888Pixel *pColor = (openni::RGB888Pixel*)colorFrame.getData();openni::VideoFrameRef  mDepthFrame;if(mDepthStream.readFrame(&mDepthFrame) == openni::STATUS_OK) {float fx,fy,fz;int i=0;//以米为单位double fScale = 0.001;openni::DepthPixel *pDepthArray = (openni::DepthPixel*)mDepthFrame.getData();for(int y = 0; y < mDepthFrame.getHeight(); y++) {for(int x = 0; x < mDepthFrame.getWidth(); x++) {int idx = x + y*mDepthFrame.getWidth();const openni::DepthPixel rDepth = pDepthArray[idx];openni::CoordinateConverter::convertDepthToWorld(mDepthStream,x,y,rDepth,&fx,&fy,&fz);fx = -fx;fy = -fy;cloud_XYZRGB->points[i].x = fx * fScale;cloud_XYZRGB->points[i].y = fy * fScale;cloud_XYZRGB->points[i].z = fz * fScale;cloud_XYZRGB->points[i].r = pColor[i].r;cloud_XYZRGB->points[i].g = pColor[i].g;cloud_XYZRGB->points[i].b = pColor[i].b;i++;}}return true;} else {std::cout << "getCloudXYZCoordinate: fail to read frame from depth stream" << std::endl;return false;}
}int main(){	//openni初始化、打开摄像头if(!init()) {std::cout << "Fail to init ..." << std::endl;return -1;}//openni创建图像流if(createColorStream() && createDepthStream())std::cout << "displayPointCloud: create color stream and depth stream ..." << std::endl;else{std::cout << "displayPointCloud: can not create color stream and depth stream ..." << std::endl;return -1;}//创建pcl云pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_XYZRGB(new pcl::PointCloud<pcl::PointXYZRGB>());cloud_XYZRGB->width = 640;cloud_XYZRGB->height = 480;cloud_XYZRGB->points.resize(cloud_XYZRGB->width*cloud_XYZRGB->height);//pcl可视化pcl::visualization::PCLVisualizer::Ptr m_pViewer(new pcl::visualization::PCLVisualizer("Viewer"));m_pViewer->setCameraPosition(0, 0, -2, 0,-1, 0, 0);m_pViewer->addCoordinateSystem(0.3);while(!m_pViewer->wasStopped()) {getCloudXYZCoordinate(cloud_XYZRGB);pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud_XYZRGB);m_pViewer->addPointCloud<pcl::PointXYZRGB>(cloud_XYZRGB,rgb,"cloud");m_pViewer->spinOnce();m_pViewer->removeAllPointClouds();}mColorStream.destroy();mDepthStream.destroy();mDevice.close();openni::OpenNI::shutdown();return 0;
}

使用
pcl::visualization::PointCloudColorHandlerCustompcl::PointXYZRGB GreenHandler(cloud_XYZRGB,0,255,0);
m_pViewer->addPointCloudpcl::PointXYZRGB(cloud_XYZRGB,GreenHandler,“cloud”);
可以将点云全部设置为绿色。

四、CMakeLists.txt

cmake_minimum_required(VERSION 2.8)project(pcl)SET(OpenNI2_SO_DIR ${PROJECT_SOURCE_DIR}/lib)find_package(PCL 1.7 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})add_executable (pcl ${PROJECT_SOURCE_DIR}/src/main.cpp)
target_link_libraries (pcl ${PCL_LIBRARIES} ${OpenNI2_SO_DIR}/libOpenNI2.so)

不同的相机需要的libOpenNI2.so不同,依个人情况修改。

  相关解决方案