外文原址:https://wiseodd.github.io/techblog/2016/11/20/levelset-segmentation/
Part 2 :图像分割
上一章我们先感性后理性地认识了LSM,它可以应用在很多方面,如波的仿真、野火仿真、气体仿真。本章我们将研究水平集方法在计算机视觉中的应用——图像分割。
基于LSM的图像分割
回忆下上一章中推导的曲面演化偏微分方程,式(1):
ϕ′=ϕ+ΔtF∥∇ϕ∥
式(1)中的F速度函数(力函数)是需要特别关注的地方,需要针对不同的应用设计不同的F函数。直观理解,F就是推动曲线演变的力。换句话说,我们可以将F理解为速度场,F描述了ϕ曲面上 每一个点的运动速度和方向(结合法向量,方向向量为单位向量,也即用1、-1来指示方向,关键还是靠F来推动演化)
当要分割一幅图像时,我们需要 从图像中推导出函数F。假设我们有一张图:
由于F是一个速度场,考虑到需要求解的偏微分方程PDE(1),我们希望F在远离目标轮廓时变化快,在目标轮廓附近时变化慢。
一种从 图像中推导F的方法是借助 边缘检测。边缘检测最简单 的方式是 取图像的梯度,式(2):
(这个公式的意思就是梯度越大演化速度越慢,因为此时处于边界附近;梯度越小演化速度越快,因为此时距离边界较远)
Sooooooo,let's do it:
Import numpy as np
Import scipy.ndimage
Import scipy.signal
Import matplotlib.pyplot as plt
From skimage import color,io
Def grad(x):
Return np.array(np.gradient(x)) # 这个结果是2通道的哦
Def norm(x,axis=0):
Return np.sqrt(np.sum(np.square(x),axis=axis))#横纵两个方向的梯度正则化为1个值
Def stopping_fun(x): #F函数
Return 1./(1.+norm(grad(x))**2)
img = io.imread('twoObj.bmp')
img = color.rgb2gray(img)
img = img - np.mean(img)
# Smooth the image to reduce noise and separation between noise and edge #becomes clear
img_smooth = scipy.ndimage.filters.gaussian_filter(img, sigma)
F = stopping_fun(img_smooth)
有了F函数,我们就可以将其直接用于PDE的求解了:
Def default_phi(x):
Phi=np.ones(x.shape[:2])
Phi[5:-5,5:-5]=-1.
Return phi
n_iter=1000
Dt=1.
for i in range(n_iter):
dphi = grad(phi)
dphi_norm = norm(dphi)
dphi_t = F * dphi_norm
phi = phi + dt * dphi_t
多次迭代后,结果如下:
这是一个非常简单的水平集分割方法。应用 更加复杂的F函数我们将得到更好 的结果。
测地线活动模型
在Geodesic Active Contour(GAC)模型中,F函数定义如下,式(3):
式中,第一项为平滑项,它使曲线 沿曲率方向移动;第二项是气球项,用于控制曲线的演化速度;最后一项是附加项,用于帮助曲线收敛
# 曲率是这么计算的哦
Def curvature(f):
fy,fx=grad(f)
Norm=np.sqrt(fx**2+fy**2)
Nx=fx/(Norm+1e-8)
Ny=fy/(Norm+1e-8)
Return div(Nx,Ny)
Def div(fx,fy):
# 图像的散度对某幅图像连续求2次梯度得到的zx_x和zy_y的和是等于散度的。换句话说div(z) = zx_x +zy_y
Fyy,fyx=grad(fy)
Fxy,fxx=grad(fx)
Return fxx+fyy
Def dot(x,y,axis=0):
Return np.sum(x*y,axis=axis)
v=1.
Dt=1.
g=stopping_fun(img_smooth)#g=stopping_fun(img_smooth,alpha)
dg=grad(g)
for i in range(n_iter):
dphi = grad(phi)
dphi_norm = norm(dphi)
kappa = curvature(phi)
smoothing = g * kappa * dphi_norm
balloon = g * dphi_norm * v
attachment = dot(dphi, dg)
dphi_t = smoothing + balloon + attachment
phi = phi + dt * dphi_t
以下为分割结果:
观测发现,该分割结果比图3更好,也即更平滑更贴合目标了
本章,我们实现了一个LSM在图像分割中的案例。我们发现 不同的速度函数F将实现不同的分割结果。