PCL获取Kinect v2点云

PCL获取Kinect v2点云


本博客主要参考网络上的教程博客,加上自己遇到的问题。

环境:win8_x64VS2013OpenCV2.4.9PCL1.7.2Kinect SDK2.0

 

 

主要参考博客:http://www.pclcn.org/bbs/forum.php?mod=viewthread&tid=1195

 

 

本博客用到的库和软件链接:http://pan.baidu.com/s/1dFw1PQD 密码:ob48

 

一、安装依赖库

 

a、安装OpenCV这里安装的是OpenCV2.4.9

推荐教程:http://blog.csdn.net/pinbodexiaozhu/article/details/39889995/

    

b、安装PCL这里安装的是PCL1.7.2

推荐教程:http://blog.csdn.net/caimagic/article/details/51395084

 

c、安装Kinect SDK2.0

直接安装,按提示操作即可。

官网SDK下载链接:https://www.microsoft.com/en-us/download/details.aspx?id=44561

安装完成后,在VS中新建空项目,

在属性管理器->C/C++->附加包含目录 添加C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\inc

属性管理器->链接器->常规->附加库目录 添加C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Lib\x86

属性管理器->链接器->输入->附加依赖项  添加

Kinect20.VisualGestureBuilder.lib    Kinect20.lib    Kinect20.Face.lib    Kinect20.Fusion.lib 

 

在解决方案资源管理器中添加下面的源文件kinect2_grabber.cppkinect2_grabber.h后编译运行即可看到点云窗口。


二、代码

 

代码源文件在网盘Kinect_v2_点云获取文件夹中的kinect2_grabber.cppkinect2_grabber.h


源码网盘链接:http://pan.baidu.com/s/1jH4iZdG 密码:9jw8


另还有CMakeLists.txt供camake编译使用

CMakeLists.txt

cmake_minimum_required( VERSION 2.8 )
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
 
project( sample )
add_executable( sample kinect2_grabber.h main.cpp )
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "sample" )
 
# Find Packages
find_package( PCL 1.7.2 REQUIRED )
find_package( KinectSDK2 REQUIRED )
 
if( PCL_FOUND AND KinectSDK2_FOUND )
  # Additional Include Directories
  include_directories( ${PCL_INCLUDE_DIRS} )
  include_directories( ${KinectSDK2_INCLUDE_DIRS} )
 
  # Preprocessor Definitions
  add_definitions( ${PCL_DEFINITIONS} )
 
  # Additional Library Directories
  link_directories( ${PCL_LIBRARY_DIRS} )
  link_directories( ${KinectSDK2_LIBRARY_DIRS} )
 
  # Additional Dependencies
  target_link_libraries( sample ${PCL_LIBRARIES} )
  target_link_libraries( sample ${KinectSDK2_LIBRARIES} )
endif()

kinect2_grabber.cpp

// Disable Error C4996 that occur when using Boost.Signals2.
#ifdef _DEBUG
#define _SCL_SECURE_NO_WARNINGS
#endif

#include "kinect2_grabber.h"
#include 

typedef pcl::PointXYZRGBA PointType;

int main( int argc, char* argv[] )
{
    // PCL Visualizer
    boost::shared_ptr viewer(
        new pcl::visualization::PCLVisualizer( "Point Cloud Viewer" ) );
    viewer->setCameraPosition( 0.0, 0.0, -2.5, 0.0, 0.0, 0.0 );

    // Point Cloud
    pcl::PointCloud::ConstPtr cloud;

    // Retrieved Point Cloud Callback Function
    boost::mutex mutex;
    boost::function::ConstPtr& )> function =
        [&cloud, &mutex]( const pcl::PointCloud::ConstPtr& ptr ){
            boost::mutex::scoped_lock lock( mutex );

            /* Point Cloud Processing */

            cloud = ptr->makeShared();
        };
    // Kinect2Grabber
  //  boost::shared_ptr grabber = boost::make_shared();
	boost::shared_ptr grabber = boost::shared_ptr(new pcl::Kinect2Grabber);
    // Register Callback Function
    boost::signals2::connection connection = grabber->registerCallback( function );

    // Start Grabber
    grabber->start();

    while( !viewer->wasStopped() ){
        // Update Viewer
        viewer->spinOnce();

        boost::mutex::scoped_try_lock lock( mutex );
        if( lock.owns_lock() && cloud ){
            // Update Point Cloud
            if( !viewer->updatePointCloud( cloud, "cloud" ) ){
                viewer->addPointCloud( cloud, "cloud" );
            }
        }
    }
    // Stop Grabber
    grabber->stop();
    
    // Disconnect Callback Function
    if( connection.connected() ){
        connection.disconnect();
    }

    return 0;
}


kinect2_grabber.h

// Kinect2Grabber is pcl::Grabber to retrieve the point cloud data from Kinect v2 using Kinect for Windows SDK 2.x.
// This source code is licensed under the MIT license. Please see the License in License.txt.

#ifndef KINECT2_GRABBER
#define KINECT2_GRABBER

#define NOMINMAX
#include 
#include 

#include 
#include 
#include 
#include 


namespace pcl
{
    struct pcl::PointXYZ;
    struct pcl::PointXYZI;
    struct pcl::PointXYZRGB;
    struct pcl::PointXYZRGBA;
    template  class pcl::PointCloud;

    template
    inline void SafeRelease( Interface *& IRelease )
    {
        if( IRelease != NULL ){
            IRelease->Release();
            IRelease = NULL;
        }
    }

    class Kinect2Grabber : public pcl::Grabber
    {
        public:
            Kinect2Grabber();
            virtual ~Kinect2Grabber() throw ();
            virtual void start();
            virtual void stop();
            virtual bool isRunning() const;
            virtual std::string getName() const;
            virtual float getFramesPerSecond() const;

            typedef void ( signal_Kinect2_PointXYZ )( const boost::shared_ptr>& );
            typedef void ( signal_Kinect2_PointXYZI )( const boost::shared_ptr>& );
            typedef void ( signal_Kinect2_PointXYZRGB )( const boost::shared_ptr>& );
            typedef void ( signal_Kinect2_PointXYZRGBA )( const boost::shared_ptr>& );

        protected:
            boost::signals2::signal* signal_PointXYZ;
            boost::signals2::signal* signal_PointXYZI;
            boost::signals2::signal* signal_PointXYZRGB;
            boost::signals2::signal* signal_PointXYZRGBA;

            pcl::PointCloud::Ptr convertDepthToPointXYZ( UINT16* depthBuffer );
            pcl::PointCloud::Ptr convertInfraredDepthToPointXYZI( UINT16* infraredBuffer, UINT16* depthBuffer );
            pcl::PointCloud::Ptr convertRGBDepthToPointXYZRGB( RGBQUAD* colorBuffer, UINT16* depthBuffer );
            pcl::PointCloud::Ptr convertRGBADepthToPointXYZRGBA( RGBQUAD* colorBuffer, UINT16* depthBuffer );

            boost::thread thread;
            mutable boost::mutex mutex;

            void threadFunction();

            bool quit;
            bool running;

            HRESULT result;
            IKinectSensor* sensor;
            ICoordinateMapper* mapper;
            IColorFrameSource* colorSource;
            IColorFrameReader* colorReader;
            IDepthFrameSource* depthSource;
            IDepthFrameReader* depthReader;
            IInfraredFrameSource* infraredSource;
            IInfraredFrameReader* infraredReader;

            int colorWidth;
            int colorHeight;
            std::vector colorBuffer;

            int depthWidth;
            int depthHeight;
            std::vector depthBuffer;

            int infraredWidth;
            int infraredHeight;
            std::vector infraredBuffer;
    };

    pcl::Kinect2Grabber::Kinect2Grabber()
        : sensor( nullptr )
        , mapper( nullptr )
        , colorSource( nullptr )
        , colorReader( nullptr )
        , depthSource( nullptr )
        , depthReader( nullptr )
        , infraredSource( nullptr )
        , infraredReader( nullptr )
        , result( S_OK )
        , colorWidth( 1920 )
        , colorHeight( 1080 )
        , colorBuffer()
        , depthWidth( 512 )
        , depthHeight( 424 )
        , depthBuffer()
        , infraredWidth( 512 )
        , infraredHeight( 424 )
        , infraredBuffer()
        , running( false )
        , quit( false )
        , signal_PointXYZ( nullptr )
        , signal_PointXYZI( nullptr )
        , signal_PointXYZRGB( nullptr )
        , signal_PointXYZRGBA( nullptr )
    {
        // Create Sensor Instance
        result = GetDefaultKinectSensor( &sensor );
        if( FAILED( result ) ){
            throw std::exception( "Exception : GetDefaultKinectSensor()" );
        }

        // Open Sensor
        result = sensor->Open();
        if( FAILED( result ) ){
            throw std::exception( "Exception : IKinectSensor::Open()" );
        }

        // Retrieved Coordinate Mapper
        result = sensor->get_CoordinateMapper( &mapper );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IKinectSensor::get_CoordinateMapper()" );
        }

        // Retrieved Color Frame Source
        result = sensor->get_ColorFrameSource( &colorSource );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IKinectSensor::get_ColorFrameSource()" );
        }

        // Retrieved Depth Frame Source
        result = sensor->get_DepthFrameSource( &depthSource );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IKinectSensor::get_DepthFrameSource()" );
        }

        // Retrieved Infrared Frame Source
        result = sensor->get_InfraredFrameSource( &infraredSource );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IKinectSensor::get_InfraredFrameSource()" );
        }

        // Retrieved Color Frame Size
        IFrameDescription* colorDescription;
        result = colorSource->get_FrameDescription( &colorDescription );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IColorFrameSource::get_FrameDescription()" );
        }

        result = colorDescription->get_Width( &colorWidth ); // 1920
        if( FAILED( result ) ){
            throw std::exception( "Exception : IFrameDescription::get_Width()" );
        }

        result = colorDescription->get_Height( &colorHeight ); // 1080
        if( FAILED( result ) ){
            throw std::exception( "Exception : IFrameDescription::get_Height()" );
        }

        SafeRelease( colorDescription );

        // To Reserve Color Frame Buffer
        colorBuffer.resize( colorWidth * colorHeight );

        // Retrieved Depth Frame Size
        IFrameDescription* depthDescription;
        result = depthSource->get_FrameDescription( &depthDescription );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IDepthFrameSource::get_FrameDescription()" );
        }

        result = depthDescription->get_Width( &depthWidth ); // 512
        if( FAILED( result ) ){
            throw std::exception( "Exception : IFrameDescription::get_Width()" );
        }

        result = depthDescription->get_Height( &depthHeight ); // 424
        if( FAILED( result ) ){
            throw std::exception( "Exception : IFrameDescription::get_Height()" );
        }

        SafeRelease( depthDescription );

        // To Reserve Depth Frame Buffer
        depthBuffer.resize( depthWidth * depthHeight );

        // Retrieved Infrared Frame Size
        IFrameDescription* infraredDescription;
        result = infraredSource->get_FrameDescription( &infraredDescription );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IInfraredFrameSource::get_FrameDescription()" );
        }

        result = infraredDescription->get_Width( &infraredWidth ); // 512
        if( FAILED( result ) ){
            throw std::exception( "Exception : IFrameDescription::get_Width()" );
        }

        result = infraredDescription->get_Height( &infraredHeight ); // 424
        if( FAILED( result ) ){
            throw std::exception( "Exception : IFrameDescription::get_Height()" );
        }

        SafeRelease( infraredDescription );

        // To Reserve Infrared Frame Buffer
        infraredBuffer.resize( infraredWidth * infraredHeight );

        signal_PointXYZ = createSignal();
        signal_PointXYZI = createSignal();
        signal_PointXYZRGB = createSignal();
        signal_PointXYZRGBA = createSignal();
    }

    pcl::Kinect2Grabber::~Kinect2Grabber() throw()
    {
        stop();

        disconnect_all_slots();
        disconnect_all_slots();
        disconnect_all_slots();
        disconnect_all_slots();

        thread.join();

        // End Processing
        if( sensor ){
            sensor->Close();
        }
        SafeRelease( sensor );
        SafeRelease( mapper );
        SafeRelease( colorSource );
        SafeRelease( colorReader );
        SafeRelease( depthSource );
        SafeRelease( depthReader );
        SafeRelease( infraredSource );
        SafeRelease( infraredReader );
    }

    void pcl::Kinect2Grabber::start()
    {
        // Open Color Frame Reader
        result = colorSource->OpenReader( &colorReader );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IColorFrameSource::OpenReader()" );
        }

        // Open Depth Frame Reader
        result = depthSource->OpenReader( &depthReader );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IDepthFrameSource::OpenReader()" );
        }

        // Open Infrared Frame Reader
        result = infraredSource->OpenReader( &infraredReader );
        if( FAILED( result ) ){
            throw std::exception( "Exception : IInfraredFrameSource::OpenReader()" );
        }

        running = true;

        thread = boost::thread( &Kinect2Grabber::threadFunction, this );
    }

    void pcl::Kinect2Grabber::stop()
    {
        boost::unique_lock lock( mutex );

        quit = true;
        running = false;

        lock.unlock();
    }

    bool pcl::Kinect2Grabber::isRunning() const
    {
        boost::unique_lock lock( mutex );

        return running;

        lock.unlock();
    }

    std::string pcl::Kinect2Grabber::getName() const
    {
        return std::string( "Kinect2Grabber" );
    }

    float pcl::Kinect2Grabber::getFramesPerSecond() const
    {
        return 30.0f;
    }

    void pcl::Kinect2Grabber::threadFunction()
    {
        while( !quit ){
            boost::unique_lock lock( mutex );

            // Acquire Latest Color Frame
            IColorFrame* colorFrame = nullptr;
            result = colorReader->AcquireLatestFrame( &colorFrame );
            if( SUCCEEDED( result ) ){
                // Retrieved Color Data
                result = colorFrame->CopyConvertedFrameDataToArray( colorBuffer.size() * sizeof( RGBQUAD ), reinterpret_cast( &colorBuffer[0] ), ColorImageFormat::ColorImageFormat_Bgra );
                if( FAILED( result ) ){
                    throw std::exception( "Exception : IColorFrame::CopyConvertedFrameDataToArray()" );
                }
            }
            SafeRelease( colorFrame );

            // Acquire Latest Depth Frame
            IDepthFrame* depthFrame = nullptr;
            result = depthReader->AcquireLatestFrame( &depthFrame );
            if( SUCCEEDED( result ) ){
                // Retrieved Depth Data
                result = depthFrame->CopyFrameDataToArray( depthBuffer.size(), &depthBuffer[0] );
                if( FAILED( result ) ){
                    throw std::exception( "Exception : IDepthFrame::CopyFrameDataToArray()" );
                }
            }
            SafeRelease( depthFrame );

            // Acquire Latest Infrared Frame
            IInfraredFrame* infraredFrame = nullptr;
            result = infraredReader->AcquireLatestFrame( &infraredFrame );
            if( SUCCEEDED( result ) ){
                // Retrieved Infrared Data
                result = infraredFrame->CopyFrameDataToArray( infraredBuffer.size(), &infraredBuffer[0] );
                if( FAILED( result ) ){
                    throw std::exception( "Exception : IInfraredFrame::CopyFrameDataToArray()" );
                }
            }
            SafeRelease( infraredFrame );

            lock.unlock();

            if( signal_PointXYZ->num_slots() > 0 ){
                signal_PointXYZ->operator()( convertDepthToPointXYZ( &depthBuffer[0] ) );
            }

            if( signal_PointXYZI->num_slots() > 0 ){
                signal_PointXYZI->operator()( convertInfraredDepthToPointXYZI( &infraredBuffer[0], &depthBuffer[0] ) );
            }

            if( signal_PointXYZRGB->num_slots() > 0 ){
                signal_PointXYZRGB->operator()( convertRGBDepthToPointXYZRGB( &colorBuffer[0], &depthBuffer[0] ) );
            }

            if( signal_PointXYZRGBA->num_slots() > 0 ){
                signal_PointXYZRGBA->operator()( convertRGBADepthToPointXYZRGBA( &colorBuffer[0], &depthBuffer[0] ) );
            }
        }
    }

    pcl::PointCloud::Ptr pcl::Kinect2Grabber::convertDepthToPointXYZ( UINT16* depthBuffer )
    {
        pcl::PointCloud::Ptr cloud( new pcl::PointCloud() );

        cloud->width = static_cast( depthWidth );
        cloud->height = static_cast( depthHeight );
        cloud->is_dense = false;

        cloud->points.resize( cloud->height * cloud->width );

        pcl::PointXYZ* pt = &cloud->points[0];
        for( int y = 0; y < depthHeight; y++ ){
            for( int x = 0; x < depthWidth; x++, pt++ ){
                pcl::PointXYZ point;

                DepthSpacePoint depthSpacePoint = { static_cast( x ), static_cast( y ) };
                UINT16 depth = depthBuffer[y * depthWidth + x];

                // Coordinate Mapping Depth to Camera Space, and Setting PointCloud XYZ
                CameraSpacePoint cameraSpacePoint = { 0.0f, 0.0f, 0.0f };
                mapper->MapDepthPointToCameraSpace( depthSpacePoint, depth, &cameraSpacePoint );
                point.x = cameraSpacePoint.X;
                point.y = cameraSpacePoint.Y;
                point.z = cameraSpacePoint.Z;

                *pt = point;
            }
        }

        return cloud;
    }

    pcl::PointCloud::Ptr pcl::Kinect2Grabber::convertInfraredDepthToPointXYZI( UINT16* infraredBuffer, UINT16* depthBuffer )
    {
        pcl::PointCloud::Ptr cloud( new pcl::PointCloud() );

        cloud->width = static_cast( depthWidth );
        cloud->height = static_cast( depthHeight );
        cloud->is_dense = false;

        cloud->points.resize( cloud->height * cloud->width );

        pcl::PointXYZI* pt = &cloud->points[0];
        for( int y = 0; y < depthHeight; y++ ){
            for( int x = 0; x < depthWidth; x++, pt++ ){
                pcl::PointXYZI point;

                DepthSpacePoint depthSpacePoint = { static_cast( x ), static_cast( y ) };
                UINT16 depth = depthBuffer[y * depthWidth + x];

                // Setting PointCloud Intensity
                point.intensity = static_cast( infraredBuffer[y * depthWidth + x] );

                // Coordinate Mapping Depth to Camera Space, and Setting PointCloud XYZ
                CameraSpacePoint cameraSpacePoint = { 0.0f, 0.0f, 0.0f };
                mapper->MapDepthPointToCameraSpace( depthSpacePoint, depth, &cameraSpacePoint );
                point.x = cameraSpacePoint.X;
                point.y = cameraSpacePoint.Y;
                point.z = cameraSpacePoint.Z;

                *pt = point;
            }
        }

        return cloud;
    }

    pcl::PointCloud::Ptr pcl::Kinect2Grabber::convertRGBDepthToPointXYZRGB( RGBQUAD* colorBuffer, UINT16* depthBuffer )
    {
        pcl::PointCloud::Ptr cloud( new pcl::PointCloud() );

        cloud->width = static_cast( depthWidth );
        cloud->height = static_cast( depthHeight );
        cloud->is_dense = false;

        cloud->points.resize( cloud->height * cloud->width );

        pcl::PointXYZRGB* pt = &cloud->points[0];
        for( int y = 0; y < depthHeight; y++ ){
            for( int x = 0; x < depthWidth; x++, pt++ ){
                pcl::PointXYZRGB point;

                DepthSpacePoint depthSpacePoint = { static_cast( x ), static_cast( y ) };
                UINT16 depth = depthBuffer[y * depthWidth + x];

                // Coordinate Mapping Depth to Color Space, and Setting PointCloud RGB
                ColorSpacePoint colorSpacePoint = { 0.0f, 0.0f };
                mapper->MapDepthPointToColorSpace( depthSpacePoint, depth, &colorSpacePoint );
                int colorX = static_cast( std::floor( colorSpacePoint.X + 0.5f ) );
                int colorY = static_cast( std::floor( colorSpacePoint.Y + 0.5f ) );
                if( ( 0 <= colorX ) && ( colorX < colorWidth ) && ( 0 <= colorY ) && ( colorY < colorHeight ) ){
                    RGBQUAD color = colorBuffer[colorY * colorWidth + colorX];
                    point.b = color.rgbBlue;
                    point.g = color.rgbGreen;
                    point.r = color.rgbRed;
                }

                // Coordinate Mapping Depth to Camera Space, and Setting PointCloud XYZ
                CameraSpacePoint cameraSpacePoint = { 0.0f, 0.0f, 0.0f };
                mapper->MapDepthPointToCameraSpace( depthSpacePoint, depth, &cameraSpacePoint );
                if( ( 0 <= colorX ) && ( colorX < colorWidth ) && ( 0 <= colorY ) && ( colorY < colorHeight ) ){
                    point.x = cameraSpacePoint.X;
                    point.y = cameraSpacePoint.Y;
                    point.z = cameraSpacePoint.Z;
                }

                *pt = point;
            }
        }

        return cloud;
    }

    pcl::PointCloud::Ptr pcl::Kinect2Grabber::convertRGBADepthToPointXYZRGBA( RGBQUAD* colorBuffer, UINT16* depthBuffer )
    {
        pcl::PointCloud::Ptr cloud( new pcl::PointCloud() );

        cloud->width = static_cast( depthWidth );
        cloud->height = static_cast( depthHeight );
        cloud->is_dense = false;

        cloud->points.resize( cloud->height * cloud->width );

        pcl::PointXYZRGBA* pt = &cloud->points[0];
        for( int y = 0; y < depthHeight; y++ ){
            for( int x = 0; x < depthWidth; x++, pt++ ){
                pcl::PointXYZRGBA point;

                DepthSpacePoint depthSpacePoint = { static_cast( x ), static_cast( y ) };
                UINT16 depth = depthBuffer[y * depthWidth + x];

                // Coordinate Mapping Depth to Color Space, and Setting PointCloud RGBA
                ColorSpacePoint colorSpacePoint = { 0.0f, 0.0f };
                mapper->MapDepthPointToColorSpace( depthSpacePoint, depth, &colorSpacePoint );
                int colorX = static_cast( std::floor( colorSpacePoint.X + 0.5f ) );
                int colorY = static_cast( std::floor( colorSpacePoint.Y + 0.5f ) );
                if( ( 0 <= colorX ) && ( colorX < colorWidth ) && ( 0 <= colorY ) && ( colorY < colorHeight ) ){
                    RGBQUAD color = colorBuffer[colorY * colorWidth + colorX];
                    point.b = color.rgbBlue;
                    point.g = color.rgbGreen;
                    point.r = color.rgbRed;
                    point.a = color.rgbReserved;
                }

                // Coordinate Mapping Depth to Camera Space, and Setting PointCloud XYZ
                CameraSpacePoint cameraSpacePoint = { 0.0f, 0.0f, 0.0f };
                mapper->MapDepthPointToCameraSpace( depthSpacePoint, depth, &cameraSpacePoint );
                if( ( 0 <= colorX ) && ( colorX < colorWidth ) && ( 0 <= colorY ) && ( colorY < colorHeight ) ){
                    point.x = cameraSpacePoint.X;
                    point.y = cameraSpacePoint.Y;
                    point.z = cameraSpacePoint.Z;
                }

                *pt = point;
            }
        }

        return cloud;
    }
}

#endif KINECT2_GRABBER


最后放上效果图:



你可能感兴趣的:(PCL点云库)