我的毕业设计用到了CPD算法,以及CPD代码工具包,当时刚开始接触CPD时在网上没找到几篇教程或是经验总结的东西。现在毕设做完了,就结合我的理解写一篇文章。可能写的会有点乱,因为我也是一时兴起想要做一下整理,所以并没有列出详细的大纲和框架就直接写了。请多包涵。

对于算法我只写我的简单理解,具体的算法推导网上已经有人写了,我的数学能力不太能够理解具体的算法推导,所以这篇文章只是用来将算法中的公式与代码的实现对应起来。希望对CPD算法的学习者能够有所帮助。

CPD工具包是用MATLAB写的,下载链接在这里:https://blog.csdn.net/kaspar1992/article/details/78629916。

一、算法的简单介绍

简单说一下点云配准算法的问题描述:对于两个需要进行配准的点云,一个点云为参考点云(或模板点云)X,另一个点云为待配准点云Y。配准过程是将待配准点云Y逐渐向参考点云移动,直到两者配准。如下图所示,这是一个简单的示意,X点集不动,Y点集向X点集移动。

现在我们假设X点集的规模为N=4个点,Y点集的规模为M=3个点。

现在计算X点集中的n0点到Y中的每一个点的距离。分别记作dn0m0,dn0m1……。CPD算法中GMM概率密度函数表示为:

其中

上式中的x-ym其实就是点与点之间的距离d,此处||x-ym||²即表示两点距离的平方。

似然函数可以写为,通过最大化该似然函数,即可得到需要的参数θ和σ²,这里的θ表示一个参数集合,θ包含了待配准点集的旋转矩阵R,平移矩阵t,缩放矩阵s,可以理解为θ={R,t,s}。而为了求解该似然函数,可以利用EM算法求解。

关于后续的算法推导,我确实一知半解,可以看看别人的推导过程。

二、文件夹中的各个文件用途

首先简单介绍一下工具包中的各个文件作用。工具包下载下来后,里面一共有3个文件夹,分别为core、data、example

1.core中即为主要的算法核心代码,其中包含如下几个文件夹。

FGT文件夹中的代码是快速CPD算法的实现。

mex文件夹中存放着几个.c文件,其中最核心的是cpd_P.c,这个代码是用于计算点与点之间的距离的,后面会讲到。

Nonrigid文件夹中的是非刚性点集配准的代码,Rigid文件夹中的是刚性点集配准代码。本文只介绍刚性点集配准代码。

utils文件夹中是一些简单的函数代码,用于生成随机点集用于测试或是用于绘制点集使配准可视化等等功能。

除了上述几个文件夹,core文件夹中还有两个文件。cpd_make用于编译mex中的.c文件。由于计算两点间的距离需要用到多次的循环运算,为了代码效率,将计算距离部分以C语言实现,工具包使用了C语言和matlab语言混合编程。

另一个cpd_register.m则是用于返回待配准点集的空间变换矩阵的函数代码,这一部分后面会讲到。

2.data文件夹中为点云测试集,以.mat的格式保存。

        这个文件夹中mat文件有的有X和Y两个数据集,一个用于刚性配准一个用于非刚性配准。

  3.example文件夹中的代码为实例,用于演示数据集的配准。

三、代码运行

接下来我通过运行一个示例的example文件,看看会用到哪几个函数。

在运行代码前记得把工具包添加入路径。

以cpd_rigid_example1.m这个文件为例,可以将其类比为main函数。初次运行时可能会报错,可以将cpd_make.m中开头的

versn删除,即可运行。

example1中的代码如下

开头加载了鱼的点集。由于这个.mat文件中有X和Y两个表格,X点集是刚性鱼点集,Y点集是非刚性鱼点集。本示例为刚性配准,因此将X赋给Y,并用一个随机生成的旋转矩阵对X点集进行变换,使两点集位置位置不同,进行测试。(注意,这里并不是对.mat文件中的数据集进行修改,而是用将.mat中的数据赋给变量X和Y)

Transform=cpd_register(X,Y,opt)这一句代码,是传入两个点云数据,调用cpd_register函数,Transform是cpd_register函数返回的空间变换的参数结构体,包含旋转矩阵,平移矩阵,缩放比例等等。

打开cpd_register函数代码,前面一大段用于初始化变量,例如是否使用刚性配准,最大迭代次数,定义误差阈值,定义离群点权重等等等等。这些参数会传入cpd_register函数中调用的cpd_rigid函数,rigid这个函数用于计算待配准点云向参考点云移动的旋转、平移等矩阵。

cpd_rigid函数中的算法步骤即为论文中的算法步骤

在cpd_rigid函数中,由于计算pmn需要每个点之间的距离,因此调用了cpd_P函数,这个函数即前文提到的用c语言写的函数。在cpd_rigd函数通过上面论文中的算法步骤计算出旋转矩阵R,平移矩阵t,缩放比例s,协方差σ²后,将参数返回给cpd_register函数,同时对Y矩阵进行相应的变换,逐次迭代。

四、算法中的公式与代码中的变量的对应

在最初学习CPD算法以及使用这个工具包的代码时,特别痛苦的一件事就是我搞不明白算法的数学公式是怎么对应到代码的实现中的。下面我就写一写我的理解。

首先从cpd_P.c中的代码开始。这部分的代码是整个算法计算的开始。因为CPD虽然是一个基于概率匹配的算法,但是计算概率时仍是以距离进行计算的。

向cpd_P.c中传入点集X和点集Y的数组。假设是平面点集配准,则D=2(若三维点集配准则D=3),X点集的数组规模为N×2,Y点集的数组规模为M×2。若以下图为例,则X点集的规模为4×2,Y点集规模为3×2。

cpd_P.c中的代码多看几遍就能理解其意思了。cpd_P.c计算了点与点之间的距离,并存入数组中。以及刚性点集配准算法流程中的P·1和P^T·1也是直接在cpd_P.c中进行了计算。cpd_P.c中的*P存放的是exp(d²/-2σ²),*P为一个M×1的一位数组。

这里我直接放上我当时做的一个笔记,如下图:

通过上面的笔记,就可以很清楚的理解cpd_P.c中计算的P1和Pt1数组中的内容是什么了。但是cpd_P.c中的Px是如何写成代码中的那种实现方式,这一点我没有推导出来,如果有人看明白希望可以解答。

可能整篇文章写的有点乱,总之先发出来,这也是我的一点粗浅的个人理解。

CPD配准算法及代码的简单理解(Coherent Point Drift)相关推荐

  1. 人工智能:深度学习算法及应用——简单理解CNN卷积神经网络并python实现(带源码)

    深度学习算法及应用 一. 实验目的 二. 实验要求 三. 实验的硬件.软件平台 四. 实验原理 1.1. 深度学习概述 1.2. 深度学习的常见结构 1.3. 卷积神经网络(CNN) **卷积** * ...

  2. 跳一跳j算法ava代码_DBSCAN聚类算法的理解与应用

    在前面的文章中,我们讲了KNN算法的原理与简单应用,KNN一种有监督学习的分类算法,也就是说该算法首先需要训练数据来进行学习之后才能对数据进行分类.在本文中我们讲到的DBSCAN聚类算法,也属于一种数 ...

  3. php和python的多线程,Python多线程以及线程锁简单理解(代码)

    本篇文章给大家带来的内容是关于Python多线程以及线程锁简单理解(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 多线程threading 模块创建线程创建自己的线程类线程通 ...

  4. 异或加密的java算法_Java使用异或运算实现简单的加密解密算法实例代码

    Java简单的加密解密算法,使用异或运算 实例1: package cn.std.util; import java.nio.charset.Charset; public class DeEnCod ...

  5. 协同过滤算法的简单理解《推荐系统实践》

    协同过滤算法的简单理解 本文主要是讲解一下<推荐系统实践>中UserCF和ItemCF这两种基于领域的推荐算法,写出自己的理解. UserCF(基于用户的协同过滤算法) 这种推荐算法的出发 ...

  6. 下料问题的列生成算法,matlab代码,简单易懂

    下料问题的列生成算法,matlab代码,简单易懂 ID:18300606016240721绿兔叽

  7. 直观地简单理解Tarjan算法(寻找有向图中的强连通图)

    简单理解Tarjan算法   按照百度百科的播报应该是读成['ta:rdʒən]?看过了几篇网络上的解释虽然都讲得比较具体但刚开始都难以理解,所以打算写一个更直观的理解方式.   Tarjan算法是求 ...

  8. MTCNN算法与代码理解—人脸检测和人脸对齐联合学习

    MTCNN算法与代码理解-人脸检测和人脸对齐联合学习 写在前面 主页:https://kpzhang93.github.io/MTCNN_face_detection_alignment/index. ...

  9. java 路由算法_几种简单的负载均衡算法及其Java代码实现

    什么是负载均衡 负载均衡,英文 名称为Load Balance,指由多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助.通过某种 负载分 ...

最新文章

  1. 一个支付案例,学会策略模式!
  2. Matlab符号运算 - 解微分方程
  3. onsrcoll和scrollTop兼容与实现
  4. 利用冒泡排序法实现select option按中文排序组件
  5. 《Breakfast At Tiffanys》
  6. MySql Socket 完成数据库的增查Demo
  7. lcd1602怎么利用按键清屏_边学边练,8个LCD1602精选电路方案大合辑
  8. 一种基于红黑树和timerfd的用户态定时器
  9. 只修改日期不修改时间(巧用convert函数)
  10. el-form-item 如何限制只能输入数字_中教云数字课程教材云平台操作答疑
  11. 咸阳机场地下停车场如何收费,咸阳机场停车收费价格
  12. MySQL函数大全,MySQL常用函数汇总
  13. JavaScript里函数中的this
  14. 每天一个linux命令——cat
  15. 【Python】所有常用Python库和功能查询表
  16. 有关PS中图片不能解锁问题
  17. SVN中删除彻底删除某一个版本
  18. poj1008 -- 玛雅历
  19. 写给扎克伯格的一封信:不要让我们失望!
  20. [内网渗透]—NTLM网络认证及NTLM-Relay攻击

热门文章

  1. 电商维权,维权方法汇总【超全】
  2. 1959-打印镂空字符三角形
  3. 对京东商品评论进行词频统计并制作词云
  4. 【sdx62】PBL阶段修改GPIO操作
  5. [sdx62]bitbake lighttpd出现NOTE: Reconnecting to bitbake server...
  6. 干草堆——acwing算法题第二天
  7. [Win32]路径操作API函数
  8. Android仿拼多多拼团堆叠头像
  9. c语言hypot函数,hypot()函数以及C ++中的示例
  10. Podium Vue客户端组件库