前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >医学图像处理案例(二十一)——一致性点漂移算法(Coherent Point Drift)

医学图像处理案例(二十一)——一致性点漂移算法(Coherent Point Drift)

作者头像
医学处理分析专家
发布2020-07-14 16:38:33
2.1K5
发布2020-07-14 16:38:33
举报

今天将分享使用一致性点漂移算法(Coherent Point Drift)来对点云数据进行配准。

1、常见配准变换

简单介绍一下什么是配准,其实很简单就是给定一个数据集,在另一个数据集中找到其所对应数据集的位置。

配准常见的有刚性变换配准,仿射变换配准和非刚性变换配准,其中刚性变换涉及到平移,旋转和各向同性缩放,仿射变换涉及到平移,旋转和各向异性缩放,倾斜等,非刚性变换就会很复杂有很多变换参数,例如分段式仿射变换,多项式模型等。

2、一致性点漂移算法简介

在论文《Point-Set Registration: Coherent Point Drift》中介绍了刚性和非刚性的配准概率方法,称为一致性点漂移算法。论文将点集之间的对应关系看成是一种概率关系问题,在最理想情况下真正的对应点的概率是1,错误的对应点概率值是0,所以直接避开点之间的坐标关系而转向使用概率值来描述这种对应关系,如果概率值越大,那么这种对应关系的确定性也就越大。

既然涉及到了概率,那就会考虑到概率模型,常见有均匀分布、二项分布、正态分布等,此时需要选择一个合适的概率模型来描述这种对应关系。如果针对一个点与一个点的对应关系,可以使用正态分布(高斯分布)来描述,所以当存在多个点时,就需要使用混合高斯模型(Gaussian Mixture Model)来进行描述了。

实际上两个点集的配准问题就是概率密度估计问题,因为其中一个点集合代表了高斯混合模型的质心,而另一个点集合代表了数据点,所以两个点集的配准问题就转化成一个概率密度估计的问题,也就转换成了求解混合高斯模型的参数问题了。

使用迭代最大化期望(最大似然法)来拟合高斯混合模型的质心,并找到质心的后验概率值。因为每个点就有一个高斯模型,因此会有多个高斯混合模型的质心需要处理,此时要对所有的高斯模型的质心的贡献度进行后验概率值归一化处理。最后一旦知道对应后验概率值后就可以求解相应变换参数了。

论文算法的核心是在于使高斯混合模型的质心做为一个整体来连贯运行,这就保留了点集的拓扑结构。具体数学公式推导可以阅读论文。

3、使用pycpd来实现一致性漂移算法的点云配准

原始论文的作者提供了matlab版本的代码实现,也有大佬用纯python复现了该算法,称为pycpd,具体项目可以点击原文链接。

安装过程很简单,用下面的命令安装即可。

代码语言:javascript
复制
pip install pycpd

作者也提供了使用案例,这里我就照搬使用,实现了刚性配准,仿射配准与非刚性配准。

代码语言:javascript
复制
from functools import partial
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from pycpd import deformable_registration
import numpy as np
import time


def visualize(iteration, error, X, Y, ax):
    plt.cla()
    ax.scatter(X[:,0],  X[:,1], X[:,2], color='red', label='Target')
    ax.scatter(Y[:,0],  Y[:,1], Y[:,2], color='blue', label='Source')
    ax.text2D(0.87, 0.92, 'Iteration: {:d}\nError: {:06.4f}'.format(iteration, error), horizontalalignment='center', verticalalignment='center', transform=ax.transAxes, fontsize='x-large')
    ax.legend(loc='upper left', fontsize='x-large')
    plt.draw()
    plt.pause(0.001)


def main():
    fish_target = np.loadtxt('data/fish_target.txt')
    X1 = np.zeros((fish_target.shape[0], fish_target.shape[1] + 1))
    X1[:,:-1] = fish_target
    X2 = np.ones((fish_target.shape[0], fish_target.shape[1] + 1))
    X2[:,:-1] = fish_target
    X = np.vstack((X1, X2))
    fish_source = np.loadtxt('data/fish_source.txt')
    Y1 = np.zeros((fish_source.shape[0], fish_source.shape[1] + 1))
    Y1[:,:-1] = fish_source
    Y2 = np.ones((fish_source.shape[0], fish_source.shape[1] + 1))
    Y2[:,:-1] = fish_source
    Y = np.vstack((Y1, Y2))

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    callback = partial(visualize, ax=ax)
    reg = deformable_registration(**{ 'X': X, 'Y': Y })
    reg.register(callback)
    plt.show()


if __name__ == '__main__':
    main()

4、配准结果

原始数据是人脸点云数据,通过对原始人脸点云数据进行变换(平移,旋转,缩放,扭曲等),如下图所示显示了原始人脸数据和变换后的人脸数据。

刚性变换配准迭代的最后结果如下所示。

仿射变换配准结果如下图所示。

非刚性变换配准结果如下图所示。

上面三种配准变换也可以结合起来使用,如下图是术前CT和术中DSA主动脉血管的中心线,CT的中心线是3d,DSA的中心线是2d的。首先采用刚性变换对3d中心线进行旋转,然后再采用仿射变换将3d中心线与2d中心线进行粗配准,最后采用非刚性变换将3d中心线与2d中心线进行精配准。

首先,对3d中心线进行刚性变换配准,结果如下图所示。

然后,在刚性变换配准的结果上进行仿射变换配准,结果如下图所示。

最后,在仿射变换配准结果上进行非刚性变换配准,结果如下图所示。

如果碰到任何问题,随时留言,我会尽量去回答的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 最新医学影像技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档