三维视觉--基于Kinect2.0深度相机的点云获取方案实现(C++版)

2023-10-30

上一篇中使用的点云获取设备是Intel Realsense d455相机,这两天接触的相机不少,也发现很多点云检测和分割的论文中使用的都是Kinect相机,今天就再分享一篇使用Kinect2.0获取点云并使用C++实现。

首先还是相机SDK的下载和安装:可以去官网下载,也可以到我之前分享的百度网盘获取。

点云获取(深度相机)方案实现C++版_低调猫熊的博客-CSDN博客

安装后再配置环境:

环境配好后,就是代码编写, 

代码如下:

#include <iostream>
#include <fstream>

#include <Windows.h>
#include <Kinect.h>

#include <opencv2/opencv.hpp>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>

using namespace std;
using namespace cv;

template<class Interface>
inline void SafeRelease(Interface*& ptr)
{
    if (ptr)
    {
        ptr->Release();
        ptr = nullptr;
    }
}

int main()
{
    // 初始化Kinect
    IKinectSensor* pKinectSensor = nullptr;
    HRESULT hr = GetDefaultKinectSensor(&pKinectSensor);
    if (FAILED(hr))
    {
        cerr << "Failed to get default Kinect sensor." << endl;
        return -1;
    }

    hr = pKinectSensor->Open();
    if (FAILED(hr))
    {
        cerr << "Failed to open Kinect sensor." << endl;
        return -1;
    }

    // 打开深度数据流和彩色数据流
    IDepthFrameReader* pDepthFrameReader = nullptr;
    IColorFrameReader* pColorFrameReader = nullptr;

    IDepthFrameSource* pDepthFrameSource = nullptr;
    hr = pKinectSensor->get_DepthFrameSource(&pDepthFrameSource);
    if (SUCCEEDED(hr))
    {
        hr = pDepthFrameSource->OpenReader(&pDepthFrameReader);
    }
    SafeRelease(pDepthFrameSource);
    if (FAILED(hr))
    {
        cerr << "Failed to open depth frame reader." << endl;
        return -1;
    }

    IColorFrameSource* pColorFrameSource = nullptr;
    hr = pKinectSensor->get_ColorFrameSource(&pColorFrameSource);
    if (SUCCEEDED(hr))
    {
        hr = pColorFrameSource->OpenReader(&pColorFrameReader);
    }
    SafeRelease(pColorFrameSource);
    if (FAILED(hr))
    {
        cerr << "Failed to open color frame reader." << endl;
        return -1;
    }

    // 打开坐标映射器
    ICoordinateMapper* pCoordinateMapper = nullptr;
    hr = pKinectSensor->get_CoordinateMapper(&pCoordinateMapper);
    if (FAILED(hr))
    {
        cerr << "Failed to get coordinate mapper." << endl;
        return -1;
    }

    // 创建窗口
    namedWindow("Color", WINDOW_AUTOSIZE);
    namedWindow("Depth", WINDOW_AUTOSIZE);

    // 定义缓冲区
    ColorSpacePoint* pColorSpacePoints = new ColorSpacePoint[512 * 424];
    UINT16* pDepthData = new UINT16[512 * 424];

    // 定义点云对象
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr pPointCloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    pPointCloud->width = 512;
    pPointCloud->height = 424;
    pPointCloud->points.resize(512 * 424);

    // 循环读取帧数据
    bool bSavePointCloud = false;
    while (true)
    {
        // 获取彩色帧
        IColorFrame* pColorFrame = nullptr;
        hr = pColorFrameReader->AcquireLatestFrame(&pColorFrame);
        if (SUCCEEDED(hr))
        {
            // 获取彩色帧数据
            UINT colorBufferSize = 1920 * 1080 * 4;
            BYTE* pColorBuffer = new BYTE[colorBufferSize];
            hr = pColorFrame->CopyConvertedFrameDataToArray(colorBufferSize, pColorBuffer, ColorImageFormat_Bgra);
            if (FAILED(hr))
            {
                cerr << "Failed to copy color frame data." << endl;
            }

            // 创建彩色图像
            Mat color(1080, 1920, CV_8UC4, pColorBuffer);
            // 显示彩色图像
            imshow("Color", color);

            // 释放彩色帧
            SafeRelease(pColorFrame);

            // 获取深度帧
            IDepthFrame* pDepthFrame = nullptr;
            hr = pDepthFrameReader->AcquireLatestFrame(&pDepthFrame);
            if (SUCCEEDED(hr))
            {
                // 获取深度帧数据
                hr = pDepthFrame->CopyFrameDataToArray(512 * 424, pDepthData);
                if (FAILED(hr))
                {
                    cerr << "Failed to copy depth frame data." << endl;
                }

                // 将深度图转换为彩色图的空间坐标
                pCoordinateMapper->MapDepthFrameToColorSpace(512 * 424, pDepthData, 512 * 424, pColorSpacePoints);

                // 释放深度帧
                SafeRelease(pDepthFrame);
            }
            else
            {
                cerr << "Failed to acquire latest depth frame." << endl;
            }
            // 显示深度图
            Mat depth(424, 512, CV_16UC1, pDepthData);
            imshow("Depth", depth);

            // 将深度图转换为点云
            for (int i = 0; i < 512 * 424; ++i)
            {
                pcl::PointXYZRGB& point = pPointCloud->points[i];
                ColorSpacePoint& colorSpacePoint = pColorSpacePoints[i];
                UINT16 depthValue = pDepthData[i];

                if (depthValue > 0 && colorSpacePoint.X >= 0 && colorSpacePoint.X < 1920 && colorSpacePoint.Y >= 0 && colorSpacePoint.Y < 1080)
                {
                    // 计算空间坐标
                    CameraSpacePoint cameraSpacePoint = { 0 };
                    pCoordinateMapper->MapDepthPointToCameraSpace({ (float)(i % 512), (float)(i / 512) }, depthValue, &cameraSpacePoint);

                    // 设置点云坐标和颜色
                    point.x = cameraSpacePoint.X;
                    point.y = cameraSpacePoint.Y;
                    point.z = cameraSpacePoint.Z;
                    point.r = color.at<Vec4b>((int)colorSpacePoint.Y, (int)colorSpacePoint.X)[2];
                    point.g = color.at<Vec4b>((int)colorSpacePoint.Y, (int)colorSpacePoint.X)[1];
                    point.b = color.at<Vec4b>((int)colorSpacePoint.Y, (int)colorSpacePoint.X)[0];
                }
                else
                {
                    // 设置无效点云坐标
                    //point.x = point.y = point.z = numeric_limits<float>::quiet_NaN();
                }
            }

        }
        else
        {
            cerr << "Failed to acquire latest color frame." << endl;
        }
        
        
       
        // 按下空格键保存点云数据为ply文件
        if (waitKey(30) == VK_SPACE)
        {
            if (!bSavePointCloud)
            {
                bSavePointCloud = true;

                // 保存点云数据为ply文件
                pcl::PLYWriter writer;
                
                writer.write("Kinect_point_cloud.ply", *pPointCloud);

                cout << "Saved point cloud data to point_cloud.ply" << endl;
            }
        }
    }

    // 释放资源
    SafeRelease(pDepthFrameReader);
    SafeRelease(pColorFrameReader);
    SafeRelease(pCoordinateMapper);
    if (pKinectSensor)
    {
        pKinectSensor->Close();
    }
    SafeRelease(pKinectSensor);
    delete[] pColorSpacePoints;
    delete[] pDepthData;

    return 0;
}

至此,就可以实现调用Kinect2.0相机获取点云了。

草稿代码可能不是那么严谨,但运行起来问题不大。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三维视觉--基于Kinect2.0深度相机的点云获取方案实现(C++版) 的相关文章

  • 使用 gcc 在 Linux 上运行线程构建块 (Intel TBB)

    我正在尝试为线程构建块构建一些测试 不幸的是 我无法配置 tbb 库 链接器找不到库 tbb 我尝试在 bin 目录中运行脚本 但这没有帮助 我什至尝试将库文件移动到 usr local lib 但这又失败了 任何的意见都将会有帮助 确定您
  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐

  • Java之美[从菜鸟到高手演变]之设计模式二

    在阅读过程中有任何问题 请及时联系 egg 邮箱 xtfggef gmail com 微博 http weibo com xtfggef 如有转载 请说明出处 http blog csdn net zhangerqing 我们接着讨论设计模
  • 变量的声明和定义

    1 声明和定义的区别 变量声明规定了变量的类型和名字 而定义是在声明的基础上还开辟了存储空间 可能还会为变量初始化一个初始值 2 c 为什么要将声明和定义分开 c 支持分离式编译机制 允许将程序分割为若干个文件 每个文件可被独立编译 而为了
  • 华为云云耀云服务器L实例评测

    目录 引出 起因 si因 解决报错 诶嘿 连上了 不出意外 就出意外了 打开数据库 what 找华为云求助 教训 备份 教训 密码 解决 1 改密码 2 新建一个MySQL 密码设置复杂一点 3 开启 binlog备份 MySQL的binl
  • Java二维数组静态以及动态初始化方法

    import java util Random public class test2 public static void main String args 二维数组静态初始化 int arr 1 2 3 4 5 6 7 8 9 Syste
  • java8 函数式接口与 Lambda 表达式

    函数式接口与 Lambda 表达式 1 函数式接口 举例复习接口的匿名实现 函数式接口 2 Lambda表达式 什么是Lambda Lambda的几种编写规则解释示例 Lambda 的方法引用与构造器引用 方法引用的解释与编写 方法引用示例
  • Winform实现ComboBox模糊查询

    1 新增项目 using System using System Collections Generic using System ComponentModel using System Data using System Drawing
  • 【Web3 系列开发教程——创建你的第一个 NFT(7)】创建一个 NFT DApp,给你的 NFT 赋予属性,例如图片

    在本文中 你将构建一个 NFT 铸币机 并学习如何通过使用 Metamask 和 Web3 工具将你的智能合约连接到 React 前端 来创建一个NFT dApp 我认为 对于具备 Web2 开发背景的开发者来说 最大的挑战之一是弄清楚如何
  • 故障诊断专家系统研究之五-----推理机制及可信度算法

    推理机制及可信度算法 在第三章和第四章中讨论了如何表示燃气轮机专家的知识以及如何把这些知识存储到知识库之中 即关于知识表示和知识库的问题 而故障诊断专家系统的另一个核心组件就是基于知识的诊断推理机 本章在前两章讨论的知识表示和知识库的基础之
  • 计算机专业大学生如何规划大学四年?

    首先必须学好计算机专业四大核心课程 数据结构 计算机网络 计算机组成原理 计算机操作系统 在此之前呢 建议学习一门面向过程和一门面向对象的语言 对我们进一步学习计算机大有裨益 比如C语言程序设计 Java程序设计 文末有福利 一 计算机专业
  • Mybatis中的StatementType

    原文 http luoyu ds iteye com blog 1517607 要实现动态传入表名 列名 需要做如下修改 添加属性statementType STATEMENT 同时sql里的属有变量取值都改成 xxxx 而不是 xxx
  • 雅可比(Jacobi)计算特征值和特征向量

    雅可比迭代法法 在图形图像中很多地方用到求矩阵的特征值和特征向量 比如主成分分析 OBB包围盒等 编程时一般都是用数值分析的方法来计算 这里介绍一下雅可比迭代法求解特征值和特征向量 雅可比迭代法的原理 网上资料很多 详细可见参考资料1 这里
  • 最小二乘法(OLS)python 实践

    参考链接 1 基本原理 https zhuanlan zhihu com p 149280941 2 python实现 https zhuanlan zhihu com p 22692029 实现结果 线性回归 coding utf 8 简
  • 2022 数学建模C题 高教社杯 含半成品论文 部分代码 全部数学模型 和全套思路

    2022 数学建模国赛B题 高教社杯 含半成品论文 部分代码 全部数学模型 和全套思路 定时更新 全部内容见 https mianbaoduo com o bread mbd Y5WUkpps 注 题目阅读后主要告诉我们的内容见标蓝的关键词
  • oracle 11g安装教程完整版

    64位WIN7 oracle11g plsql安装 上部转自Oracle 11g R2 for Win7旗舰版 64位 的安装步骤 1 下载Oracle 11g R2 for Windows的版本 下载地址 http www oracle
  • MemTest64内存测试

    MemTest64是一款测试电脑内存稳定性的测试 软件同时支持32位64位运行环境 界面如下 一 使用步骤 设定使用模式 点击开始 二 各个设置项说明 测试内存 可打开任务管理器查看内存和CPU使用情况 选择合适内存值 无限制运行 建议慎用
  • Spring Boot的底层原理

    一 Spring Boot简介 1 什么是Spring Boot Spring Boot是由Pivotal团队提供的框架 其设计目的是用来简化新Spring应用的初始搭建以及开发过程 该框架使用了特定的方式 继承starter 约定优先于配
  • Java基础:Stream流常用方法

    获取Stream流的方式 java util stream Stream 是Java 8新加入的流接口 并不是一个函数式接口 获取一个流非常简单 有以下几种常用的方式 所有 Collection 集合都可通过 stream 默认方法获取流
  • 【uniapp项目路由,配置,修改uni ui默认样式,小程序端不生效问题】

    1 对不同平台进行不同配置或样式 对不同端的css样式不一样 使用 ifdef endif 包裹 其中MP表示小程序端 表仅在小程序端是那个样式 ifdef APP PLUS margin top 88rpx endif ifdef H5
  • isis安装指南(Liunx版本)+ ASP

    ISIS Integrated Software for Imagers and Spectrometers 是一个数字图像处理软件包 用于处理当前和过去 NASA 和国际行星任务收集的图像 例如 从PDS下载的LRO月球影像数据源文件为I
  • 三维视觉--基于Kinect2.0深度相机的点云获取方案实现(C++版)

    上一篇中使用的点云获取设备是Intel Realsense d455相机 这两天接触的相机不少 也发现很多点云检测和分割的论文中使用的都是Kinect相机 今天就再分享一篇使用Kinect2 0获取点云并使用C 实现 首先还是相机SDK的下