目录
活动轮廓模型,也称为Snake模型,是一种基于能量最小化原理的图像分割技术,广泛应用于目标边缘检测、图像分割等领域。该方法由Michael Kass等人于1988年提出,旨在通过迭代优化过程找到图像中目标的精确边界。其核心思想是定义一个参数化的闭合曲线(轮廓),并使其在图像梯度等特征引导下向目标边界收敛。活动轮廓模型通过一个连续、可变形的曲线C(s)来逼近图像中感兴趣对象的边界,其中s是曲线上的参数化变量,通常取值范围为[0,1]。该曲线在每一步迭代中根据能量函数最小化的原则进行调整,直至收敛至图像的真实边界。
1.能量函数构建
活动轮廓模型的能量函数通常由内部能量(Internal Energy)、外部能量(External Energy)和图像力(Image Forces)三部分组成,旨在平衡轮廓的平滑性、边界契合度及形状约束。
内部能量(保持轮廓平滑性): 内部能量鼓励轮廓保持平滑,避免出现不必要的波动。常用的一阶导数(连续性)和二阶导数(曲率)项来衡量:
外部能量(适应图像特征): 外部能量促使轮廓向图像中特征显著变化的区域(如边缘)靠拢。这通常通过图像梯度来实现:
图像力(引导力): 图像力可以是梯度向量场,直接引导轮廓向边缘靠近,也可以包括其他先验知识,如形状约束或区域信息。
综合考虑,活动轮廓模型的整体能量函数可表示为:
2.优化求解
活动轮廓模型的优化通常采用梯度下降法或其他数值优化方法。针对能量函数的最小化,需要计算其梯度,并据此更新轮廓位置。具体步骤如下:
随着时间的推移,活动轮廓模型经历了多次改进,例如引入活动轮廓的自适应性(Active Shape Models, ASM)和活动外观模型(Active Appearance Models, AAM),以及引入水平集方法(Level Set Methods)来处理拓扑变化,使得轮廓可以分裂和合并,更加灵活地适应复杂的边界变化。
3.MATLAB程序
..................................................................
for J = 1:Iter_Num
%找到分界点
index = find(phi<2 & phi>-2);
[R2,C2] = ind2sub(size(phi),index);
K = zeros(size(index));
d_T = zeros(size(index));
Pt_in = find(phi<0);
Pt_out = find(phi>0);
%计算概率密度函数
pin = func_pdf(I(Pt_in))';
pout = func_pdf(I(Pt_out))';
%计算面积
Area_in = numel(Pt_in);
Area_out= numel(Pt_out);
T = log((pin+Sm)./(pout+Sm));
D = sqrt(mean(T.^2) - mean(T).^2);
for i = 1:numel(index)
nr = R2(i);
nc = C2(i);
ind = index(i);
%边界条件
if (nr+1) >= R2
nr = R-1;
end
if (nr-1) <= 0
nr = 2;
end
if (nc+1) >= C2
nc = C-1;
end
if (nc-1) <= 0
nc = 2;
end
%一阶差分,二阶差分
phi_x = phi(nr,nc+1) - phi(nr,nc-1);
phi_y = phi(nr+1,nc) - phi(nr-1,nc);
phi_xx = phi(nr,nc+1) - 2*phi(nr,nc) + phi(nr,nc-1);
phi_yy = phi(nr+1,nc) - 2*phi(nr,nc) + phi(nr-1,nc);
phi_xy =-0.25*phi(nr-1,nc-1)-0.25*phi(nr+1,nc+1)+0.25*phi(nr-1,nc+1)+0.25*phi(nr+1,nc-1);
%梯度
norm = sqrt(phi_x.^2 + phi_y.^2);
K(i) =((phi_x.^2.*phi_yy + phi_y.^2.*phi_xx - 2*phi_x.*phi_y.*phi_xy)./(phi_x.^2 + phi_y.^2 +Sm).^(3/2)).*norm;
%能量最小化
delta = func_energymin(h-(I(ind)+1),1);
delta = delta/(sum(delta));
G = (1/Area_in - 1/Area_out) - delta.*(1./(Area_in*pin+Sm) + 1./(Area_out*pout+Sm));
d_T(i) = (1./D) * (mean(T.*G)-mean(T)*mean(G))*norm;
d_T(i) = 0.25*sign(d_T(i));
end
e = d_T + K/8;
max_e = max(abs(e));
phi(index) = phi(index) + (0.4/(max_e+Sm))*(e);
%更新
phi = func_diff(phi);
%动态显示分割效果
if mod(J,5) == 0
J
imshow(uint8(I));
hold on;
contour(phi,[0,0],'r','linewidth',2);
drawnow;
end
hold off;
end
%输出分割效果图
phi2 = im2bw(phi);
[R,C] = size(phi2);
Object = zeros(R,C,3);
for i = 1:R
for j = 1:C
if phi2(i,j)==0
Object(i,j,1) = Irgb(i,j,1);
Object(i,j,2) = Irgb(i,j,2);
Object(i,j,3) = Irgb(i,j,3);
end
end
end
end
end
function f = func_energymin(x,sigma)
f = (1/2/sigma)*(1+cos(pi*x/sigma));
b = (x<=sigma) & (x>=-sigma);
f = f.*b;
end
up4093
4.仿真结果
算法会对该运动目标进行实时的轮廓跟踪,为背景的替换奠定了基础。
优点:可以实现背景替换和目标的跟踪;
缺点:由于进行轮廓的跟踪,比较复杂,算法仿真较慢,如果要做实时的情况,需要进一步简化算法,简化场景。另外就是对于背景太复杂的情况,就没法跟踪(多数跟踪算法都有这个问题,但影响不大,只是在轮廓跟踪的时候影响就比较大)