Our approach results in state of the art accuracy and very fast runtimes, while providing diffeomorphic guarantees.
这片论文提供了SOTA的配准方式,并且使用了diffeomorphic(微分同胚)。
diffeomorphic 微分同胚
deformation field 变形场
ordinary differential equation (ODE) 常微分方程
假设两个三维图片满足: ϕ = R 3 → R 3 \phi = R^3 \rightarrow R^3 ϕ=R3→R3,表示从一个图片的坐标到另外一个图片的坐标的变形场;
假设我们拥有了 t ∈ [ 0 , 1 ] t\in [0,1] t∈[0,1]的所有静态速度场,那么我们就可以integrate(整合)所有的速度场,从而从 ϕ ( 0 ) \phi^{(0)} ϕ(0)推断出 ϕ ( 1 ) \phi^{(1)} ϕ(1)的图片。(也就是0时刻的位移厂推出1时刻的位移场);
总的来说,我感觉就是对于部分图片变化太大,所以可能不存在静态位移场,所以用速度场来计算位移场。而这个微分同胚的推断,通过李代数和群论,得到的结论如下:
ϕ ( 1 ) = ϕ ( 1 / 2 ) c o m p o s i t i o n ϕ ( 1 / 2 ) \phi^{(1)} = \phi^{(1/2)} composition \phi^{(1/2)} ϕ(1)=ϕ(1/2)compositionϕ(1/2)
这部分我也不太能说明具体的含义,在voxelmorph的github代码中体现为:
class VecInt(nn.Module):
"""
Integrates a vector field via scaling and squaring.
"""
def __init__(self, inshape, nsteps):
super().__init__()
assert nsteps >= 0, 'nsteps should be >= 0, found: %d' % nsteps
self.nsteps = nsteps
self.scale = 1.0 / (2 ** self.nsteps)
self.transformer = SpatialTransformer(inshape)
def forward(self, vec):
vec = vec * self.scale
for _ in range(self.nsteps):
vec = vec + self.transformer(vec, vec)
return vec
重点看最后一行,vec = vec + self.transformer(vec,vec),这个刚好对应上面的:
这一块我的理解也就止步于此,进一步的可能需要李代数和群论的知识把。
模型结构不复杂:
我直接在代码中标记注释,来学习这个模型结构的过程。
def forward(self, source, target, registration=False):
'''
Parameters:
source: Source image tensor.
target: Target image tensor.
registration: Return transformed image and flow. Default is False.
'''
# 先把fixed和moving两个图片拼接起来,放到Unet模型中,提取中一个特征
x = torch.cat([source, target], dim=1)
x = self.unet_model(x)
# 把特征转换成速度场
flow_field = self.flow(x)
# 对速度场做下采样
pos_flow = flow_field
if self.resize:
pos_flow = self.resize(pos_flow)
preint_flow = pos_flow
# 这个是如果使用了双向配准的话
neg_flow = -pos_flow if self.bidir else None
# 微分同胚的整合
if self.integrate:
pos_flow = self.integrate(pos_flow)
neg_flow = self.integrate(neg_flow) if self.bidir else None
# 把尺寸恢复到原来的尺寸
if self.fullsize:
pos_flow = self.fullsize(pos_flow)
neg_flow = self.fullsize(neg_flow) if self.bidir else None
# 计算这个速度场作用在moving上的结果,如果使用了双向配准,则还需要把速度场反向作用在fixed图片上
y_source = self.transformer(source, pos_flow)
y_target = self.transformer(target, neg_flow) if self.bidir else None
# return non-integrated flow field if training
if not registration:
return (y_source, y_target, preint_flow) if self.bidir else (y_source, preint_flow)
else:
return y_source, pos_flow
整个网络也不难理解,其实这个voxelmorph代码中已经使用了微分同胚和双向配准的方案,目前使用变分推断的prob-voxelmorph模型github仓库中作者还没有提供torch的代码,所以目前还没有这个部分。
关于voxelmorph先介绍这么多,个人的心得为: