使用PCL显示Azure Kinect采集到的彩色点云

使用PCL显示Azure Kinect采集到的点云

参考文章,大佬介绍的非常好。

我这里希望能显示并保存彩色点云并借此学习下SDK的基础使用,所以并不如上述参考文章周密复杂,只写了段简单简陋的代码。

键盘退出响应可能有些问题,其他功能性尚好。

代码如下

#include <k4a/k4a.hpp>

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <chrono>

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;
using namespace pcl;

bool save_flag = false;
bool quit_flag = false;

void keyboard_event(const visualization::KeyboardEvent& event, void* nothing){
    if(event.getKeySym() == "s" && event.keyDown()){
        save_flag = true;
    }else if(event.getKeySym() == "q" && event.keyDown()){
        quit_flag = true;
    }
}

void pcl_azure_kinect_display(){
    uint32_t device_count = 0;
    k4a::device device = NULL;
    k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;

    //get the number of connected devices
    device_count = k4a::device::get_installed_count();
    if(device_count == 0){
        cout << "No K4A devices found" << endl;
        return;
    }

    //open the defaule device
    device = k4a::device::open(K4A_DEVICE_DEFAULT);
    if(device == NULL){
        cout << "Failed to opend device" << endl;
        device.close();
        return;
    }

    //set config parameter
    config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32;
    config.color_resolution = K4A_COLOR_RESOLUTION_3072P;
    config.depth_mode = K4A_DEPTH_MODE_WFOV_UNBINNED;
    config.camera_fps = K4A_FRAMES_PER_SECOND_15;
    config.synchronized_images_only = true;

    //start device
    device.start_cameras(&config);
    //should catch errors here
    
    //get images and convert to PCL format
    k4a::capture capture;
    k4a::image k4a_rgba_image;
    k4a::image k4a_depth_image;

    PointCloud<PointXYZRGBA>::Ptr cloud_rgba(new PointCloud<PointXYZRGBA>);
    boost::shared_ptr<visualization::PCLVisualizer> viewer (new visualization::PCLVisualizer("Point Cloud Viewer"));
    viewer -> registerKeyboardCallback(&keyboard_event, (void *)NULL);
    viewer -> setCameraPosition(0.0, 0.0, -2500.0, 1.0, -1.0, 1.0);

    while(true){
        if(device.get_capture(&capture, chrono::milliseconds(0))){
            k4a_rgba_image = capture.get_color_image();
            k4a_depth_image = capture.get_depth_image();

            //get calibration and transformation information
            k4a::calibration k4a_device_calibration = device.get_calibration(config.depth_mode, config.color_resolution);
            k4a::transformation k4a_device_transformation = k4a::transformation(k4a_device_calibration);
            
            //create k4a point cloud image format
            k4a::image k4a_xyz_image = NULL;
            k4a_xyz_image = k4a::image::create(K4A_IMAGE_FORMAT_CUSTOM, 
                                            k4a_depth_image.get_width_pixels(), 
                                            k4a_depth_image.get_height_pixels(), 
                                            k4a_depth_image.get_width_pixels() * 3 * (int)sizeof(int16_t));
         
            //create k4a transformed color image format
            k4a::image k4a_transformed_rgba_image = k4a::image::create(K4A_IMAGE_FORMAT_COLOR_BGRA32,
                                                                    k4a_depth_image.get_width_pixels(),
                                                                    k4a_depth_image.get_height_pixels(),
                                                                    k4a_depth_image.get_width_pixels() * 4 *(int)sizeof(uint8_t));

            //transformation
            k4a_device_transformation.depth_image_to_point_cloud(k4a_depth_image, K4A_CALIBRATION_TYPE_DEPTH, &k4a_xyz_image);
            k4a_device_transformation.color_image_to_depth_camera(k4a_depth_image, k4a_rgba_image, &k4a_transformed_rgba_image);

            //set point cloud parameter
            int point_height = k4a_xyz_image.get_height_pixels();
            int point_width = k4a_xyz_image.get_width_pixels();
            cloud_rgba -> width = point_width;
            cloud_rgba -> height = point_height;
            cloud_rgba -> is_dense = false;
            cloud_rgba -> points.resize(cloud_rgba -> height * cloud_rgba -> width);

            int16_t *k4a_xyz_image_data = (int16_t *)(void *)(k4a_xyz_image.get_buffer());
            uint8_t *k4a_transformed_rgba_image_data = (uint8_t *)(void *)(k4a_transformed_rgba_image.get_buffer());

            for(int i = 0; i < point_width * point_height; ++i){
                PointXYZRGBA point;
                point.x = k4a_xyz_image_data[3 * i + 0];
                point.y = k4a_xyz_image_data[3 * i + 1];
                point.z = k4a_xyz_image_data[3 * i + 2];
                point.b = k4a_transformed_rgba_image_data[4 * i + 0];
                point.g = k4a_transformed_rgba_image_data[4 * i + 1];
                point.r = k4a_transformed_rgba_image_data[4 * i + 2];
                point.a = k4a_transformed_rgba_image_data[4 * i + 3];
                cloud_rgba -> points[i] = point;
            }
            if(save_flag){
                string timestamp = to_string(k4a_rgba_image.get_device_timestamp().count());
                string fileName = "PCD/" + timestamp + ".pcd";
                io::savePCDFile(fileName, *cloud_rgba);
                save_flag = false;
            }
            if(!viewer -> wasStopped()){
                viewer -> spinOnce(100);
                //boost::this_thread::sleep (boost::posix_time::microseconds (100000));
                if(!viewer -> updatePointCloud(cloud_rgba, "cloud")){
                    viewer -> addPointCloud(cloud_rgba, "cloud");
                }
            }
        }
        if(quit_flag){
            viewer-> close();
            k4a_rgba_image.reset();
            k4a_depth_image.reset();
            device.close();
            break;
        }
    }
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值