Kass等人最早于1988年提出了主动轮廓模型,该方法通过构造能量函数,从而将图像分割转化为求解能量泛函极值的问题,其核心思想在于,作者认为和之前的分割方法相比,在不同的图像解读(image interpretation)任务中,表观或者浅层次(level set)的图像判读任务应该需要一些深层次(high leve)的图像信息,并论文[1]中进行了举例分析,有兴趣的同学可以自行翻阅论文查看,这也和主动轮廓模型的两大特点不谋而合:全局性和可拓展性。全局性也就是说在图像处理任务进行中,不仅要关注局部区域或者边缘信息,同样也要关注图像或曲线的整体信息如曲线整体的长度和曲率等。再者针对不同的图像特点,能够设计或者添加个性化的分割策略,接下来我将根据公式对此进一步分析。 最后还有一个限制项 好了,终于到了激动人心的实现环节了,大家是不是跟我一样激动的直搓手,哈哈哈哈哈哈哈 首先我们定义能量函数: 接下来就是整个离散化过程了,首先,我们先明确一下概念,上式中的 看完上面的离散化过程,是不是大家现在都胸有成竹,跃跃欲试,蠢蠢欲动啦,哈哈,接下来就让我们一起开始愉快的coding吧。 代码实现总共分为如下几个步骤: 计算结果,撒花,撒花,撒花! 未完待续 未完待续从零到一实现snake算法
1、Snake算法原理
对于图像
I(x,y),C(s)=C(x(s),y(s))为演化曲线,定义snake模型的能量函数为:
Esnake=Eint+Eext 这里我们区分内部能量和外部能量的依据就是看它是否和演化曲线本身的特性相关。比如说下式中,定义内部能量项的两部分内容分别代表的就是曲线的长度和曲率:
Eint=∫0121∗(α(s)∣cs(s)∣2+β(s)∣css(s)∣2)ds 其中公式中的两项内容分别表示的就是曲线的长度项和曲线的光滑程度,
α(s)和
β(s)可以根据曲线上某一点的特征进行个性化处理,但是大多数情况下我们一般定义它们为常数,用于调节曲线长度项和光滑程度占比。
而外部能量项通常由两部分组成构成:
Eext=Eimg+Econs
Eimg通常表示和图像相关的外部能量项目,主要包含如下三种信息,
(1)
Eline=∫01I(x(s),y(s))ds
Eedge=∫01−∣∇I(x(s),y(s))ds,
Eline=∫01−gδ∗∇2I(x(s),y(s))ds在实际使用中图像的梯度信息
Eedge使用的较为广泛,以及后面的实现过程中,我们也会用
Eedge作为图像力,负号的作用就在于,在边缘梯度较大的情况下,整体的能量泛函越小,曲线也就更加趋向于演化到图像的边缘位置。
Econ,这一项就是对曲线演化添加一定的限制作用,比如限制整体曲线到某一点或者某一区域
R的距离:
Econ=∫01∣∣C(x(s),y(s))−R∣∣ds具体的情况大家可以根据图片特点或者需求灵活定义。2、基于曲线演化的实现方法
开始之前我先说明两点内容:1)本次实现过程基于较为简单基础的能量泛函,大家可以先实现体验一边,然后再触类旁通,举一反三;2)以方面需要对一些数学知识进行回顾分析,另一方面希望大家仔细品一品从连续到离散的变化过程。2.1演化方程推导
Esnake=∫0121∗(α∣cs(s)∣2+β∣css(s)∣2−∣∇I(x(s),y(s))∣2)ds,当能量函数最小时,就可以获得
C(x(s),y(s))的曲线方程,本质上这也是一个求能量泛函极值的问题,直接根据欧拉-拉格朗日方程(变分原理),当能量泛函取极值时,应满足:
−αc′′(s)+βc′′′′(ss)+∇Eext=0 可是就算推到这种程度我们以然没办法直接求出曲线
c(x(s),y(s)),尤其是我们希望公式能够以偏微分方程的形式出现,这样我们就可以利用计算机进行编程序迭代计算了,于是我们在曲线中引入了一个辅组变量
t,则解可以表示为
c(t,s),随时间变化的解
c(t,s)应该使得能量函数逐渐变小(推导过程后续会补充),从而可以得出:
∂t∂c(s)=αc′′(s)−βc′′′′(ss)−∇Eext2.2离散化过程
s表示什么意思,因为我们看到的图片都是离散的点,所以我们刚开定义初始化的snake曲线时,实际上定义的也就是一系列离散的点的集合,而曲线的演化过程实际上也就是这些固定数目的点的演化过程,离散化后,我们用
i表示
s,那假设初始化的snake曲线有
N个点,那
i∈[0,N−1],且
x[N]=x[0],x[N+1]=x[2]....,那么对于曲线上任一点
c(x(i),y(i)):
x′′[i]=x[i−1]−2x[i]+x[i+1]
x′′′′[i]=x[i−2]−4x[i−1]+6x[i]−4x[i+1]+x[i+2]对y也是同理,假设图像
x方向和
y方向的梯度为
G(x,y)(均为正值),那外部力则分别为
Gx[x,y],Gy[x,y],假定每次迭代后,曲线变化较小,我们用
Gt−1(x,y)代替
Gt(x,y),那么对任一点
c(x(i),y(i))就可以推导出离散后的公式为:
∂t∂xt[i]=α(xt[i−1]−2xt[i]+xt[i+1])+β(−xt[i−2]+4xt[i−1]−6xt[i]+4xt[i+1]−xt[i+2])+Gx(xt[i],yt[i])用
λ表示步长,则可以进一步表示为:
λxt[i]−xt−1[i]=α(xt[i−1]−2xt[i]+xt[i+1])+β(−xt[i−2]+4xt[i−1]−6xt[i]+4xt[i+1]−xt[i+2])+Gx(xt−1[i],yt−1[i])同理,
λyt[i]−yt−1[i]=α(yt[i−1]−2yt[i]+yt[i+1])+β(−yt[i−2]+4yt[i−1]−6yt[i]+4yt[i+1]−yt[i+2])+Gy(yt−1[i],yt−1[i]) ,如果一条曲线上有
N个点,那就对
x和
y分别列出
N个式子,如果用矩阵表示的话,那就是:
λXt−Xt−1=AXt+Gx(xt−1,yt−1)矩阵A则为:
⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛−2α+6βα+4β−β00⋮−βα+4βα+4β−2α+6βα+4β−β0⋮0−β−βα+4β−2α+6βα+4β−β⋮000−βα+4β−2α+6βα+4β⋱0000−βα+4β−2α+6β⋮00000−βα+4β00⋯⋯⋯⋯⋯⋯⋯−β0000−2α+6βα+4βα+4β−β000α+4β−2α+6β⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞,求解矩阵即可得出:
Xt=(1−λA)−1Xt−1+λGx(Xt−1,Yt−1)
Yt=(1−λA)−1Yt−1+λGy(Xt−1,Yt−1)至此,需要的核心演化公式到手。2.3 代码实现
声明使用的依赖库主要有:import numpy as np import cv2 import matplotlib.pyplot as plt from pylab import* import skimage.filters as filt
随手用windows画图工具画了个圆(简约派):
然后读入图片,注意Image = cv2.imread('xxx.bmp',1) image = cv2.cvtColor(Image,cv2.COLOR_BGR2GRAY) img = np.array(image,dtype = np.float) plt.imshow(img,cmap = 'gray') # 读入灰度图 print(shape(img))
t = np.linspace(0,2*np.pi,60,endpoint = True) y = 100+30*np.cos(t) x = 100+30*np.sin(t)
alpha = 0.001 beta = 0.4 gamma = 100 # 迭代步长 sigma = 20 # 滤波用的高斯分布参数 iterations = 300 # 迭代次数
N = np.size(x) a = gamma*(2*alpha+6*beta)+1 b = gamma*(-alpha-4*beta) c = gamma*beta p = np.zeros((N,N),dtype=np.float) p[0] = np.c_[a,b,c,np.zeros((1,N-5)),c,b] print(p[0].shape) for i in range(N): p[i] = np.roll(p[0],i) p = np.linalg.inv(p)
smoothed = cv2.GaussianBlur((img-img.min()) / (img.max()-img.min()),(89,89),sigma) giy,gix = np.gradient(smoothed) gmi = (gix**2+giy**2)**0.5 gmi = (gmi - gmi.min()) / (gmi.max() - gmi.min()) Iy,Ix = np.gradient(gmi)
def fmax(x,y): x[x < 0] = 0 y[y < 0] = 0 x[x > img.shape[1]-1] = img.shape[1]-1 y[y > img.shape[0]-1] = img.shape[0]-1 return y.round().astype(int),x.round().astype(int)
plt.plot(y,x,'.') for i in range(iterations): fex = Ix[fmax(x,y)] fey = Iy[fmax(x,y)] x = np.dot(p,x+gamma*fex) y = np.dot(p,y+gamma*fey) if i%10 ==0: plt.plot(x,y,'.') plt.show()
2.4 讨论分析
3、基于水平集的实现方法
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算