基于Kinect 2.0深度摄像头的三维重建

刚今天验收的实验,记录一下。是比较基础的三维重建内容。算是三维重建入门。系统:windows环境:visual studio 2013语言:c++相关:OpenCV 2、Kinect SDK 2.0、PCL库内容:  使用Kinect 2.0拍摄获取深度图,将彩色图与深度图配准生成点云;  然后每次拍摄得到的点云用ICP算法进行融合,形成完整点云(每次拍摄仅做微...
摘要由CSDN通过智能技术生成

刚今天验收的实验,记录一下。

是比较基础的三维重建内容。

算是三维重建入门。

系统:windows

环境:visual studio 2013

语言:c++

相关:OpenCV 2、Kinect SDK 2.0、PCL库

内容:

  使用Kinect 2.0拍摄获取深度图,将彩色图与深度图配准生成点云;

  然后每次拍摄得到的点云用ICP算法进行融合,形成完整点云(每次拍摄仅做微小偏移);

  之后稍微对点云做了些许处理;

  还添加了回档的功能;

声明:

  有挺多借鉴博客与参考资料的,太多懒得写,假装忘了~

原理:(以下不对变量作用作解释,具体可参照变量名猜测,完整代码最后给出)

  流程图如下

 

  1.关于彩色图与深度图的配准,官方文档给出了如下3个坐标系:

  Kinect中总共有着3种坐标空间:

    1.相机空间(Camera space):拥有三个坐标轴,假设kinect面朝正前方,那么X轴向左递增,Y轴向上递增,Z轴向前递增。

    2.深度空间(Depth space):拥有三个坐标轴,其中x、y分别是深度图中像素的位置,z轴为像素的深度值。

    3.色彩空间(Color space):拥有两个坐标轴,其中x、y分别是彩色图像中像素的位置。

  由此,如果知道参数其实自己也能算,但是kinect事实上已经给出了函数。如下图所示

 

  下图为单次生成的点云:

 

  2.关于ICP算法点云配准:

  它的本质思路如下:

    1.计算两个点云之间的匹配关系;

    2.计算旋转平移矩阵;

    3.旋转平移源点云。

    4.如果误差达到要求或者迭代次数够了,则退出,否则回到第一步。

  具体实现可以参照原论文。

  这里使用的是PCL库里自带的实现

  接下来几幅图是点云融合过程(两个点云,慢慢融合)

融合效果:

 

  3.点云处理,都是水水的实验性的处理,

    1.第一种是简单的按照y轴进行颜色变换

    2.第二种是根据高度生成水面

    3.第三种是三角网格化

    详情见代码

代码:

 

#ifndef KINECT_FXXL_H
#define KINECT_FXXL_H

#include <Kinect.h>

#endif
KinectFxxL.h
#include <Kinect.h>
#include "KinectFxxL.h"
KinectFxxL.cpp
#ifndef TEST_FXXL_H
#define TEST_FXXL_H

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/opencv.hpp>  

using namespace std;
using namespace cv;

typedef unsigned short UINT16;

void showImage(Mat tmpMat, string windowName = "tmpImage");

Mat convertDepthToMat(const UINT16* pBuffer, int width, int height);

string convertIntToString(int num);

#endif
OpenCVFxxL.h
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/opencv.hpp>  

#include "OpenCVFxxL.h"

#define pause system("pause")

typedef unsigned short UINT16;

using namespace std;
using namespace cv;

void showImage(Mat tmpMat, string windowName)
{
    imshow(windowName, tmpMat);
    if (cvWaitKey(0) == 27)        //ESC键值为27
        return;
}

Mat convertDepthToMat(const UINT16* pBuffer, int width, int height)
{
    Mat ret;
    uchar* pMat;
    ret = Mat(height, width, CV_8UC1);
    pMat = ret.data;    //uchar类型的指针,指向Mat数据矩阵的首地址
    for (int i = 0; i < width*height; i++)
        *(pMat + i) = *(pBuffer + i);
    return ret;
}

string convertIntToString(int num)
{
    string ret = "";
    if (num < 0) return puts("the function only fits positive int number"), "";
    while (num) ret += (num % 10) + '0', num /= 10;
    reverse(ret.begin(), ret.end());
    if (ret.size() == 0) ret += "0";
    return ret;
}
OpenCVFxxL.cpp
#ifndef PCL_FXXL_H
#define PCL_FXXL_H

#include <time.h>
#include <stdlib.h>
#include <map>
#include <time.h>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <thread>
#include <mutex>
#include <queue>
#include <boost/make_shared.hpp>                //boost指针相关头文件
#include <pcl/io/io.h>  
#include <pcl/visualization/cloud_viewer.h>  
#include <pcl/point_types.h>                    //点类型定义头文件
#include <pcl/point_cloud.h>                    //点云类定义头文件
#include <pcl/point_representation.h>            //点表示相关的头文件
#include <pcl/io/pcd_io.h>                        //PCD文件打开存储类头文件
#include <pcl/filters/voxel_grid.h>                //用于体素网格化的滤波类头文件 
#include <pcl/filters/filter.h>                    //滤波相关头文件
#include <pcl/features/normal_3d.h>                //法线特征头文件
#include <pcl/registration/icp.h>                //ICP类相关头文件
#include <pcl/registration/icp_nl.h>            //非线性ICP 相关头文件
#include <pcl/registration/transforms.h>        //变换矩阵类头文件
#include <pcl/visualization/pcl_visualizer.h>    //可视化类头文件
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/surface/gp3.h>
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/opencv.hpp>
#include <cv.h>
#include "OpenCVFxxL.h"

#define shapeCloud(x) x->width=1,x->height=x->size()
#define GAP_NORMAL 0.001
#define GAP_TRANSPARENT 0.005
#define random(x) (rand()%x)

using namespace cv;
using namespace std;
using namespace pcl;
using pcl::visualization::PointCloudColorHandlerGenericField;
using pcl::visualization::PointCloudColorHandlerCustom;

typedef PointXYZRGBA PointT;
typedef PointCloud<PointT> PointCloudT;
typedef PointXYZ PointX;
typedef PointCloud<PointX> PointCloudX;
typedef PointCloud<PointNormal> PointCloudWithNormals;

extern boost::shared_ptr<pcl::visualization::PCLVisualizer> visualizer;
extern bool iterationFlag_visualizer;

void makeBall(PointCloudT::Ptr cloud, double x_p, double y_p, double z_p, int r_color, in
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值