基于Graph-Cut算法的图像目标分割matlab仿真

1.算法描述

       Graph cuts是一种十分有用和流行的能量优化算法,在图像处理领域普遍应用于前后背景分割(Image segmentation)、立体视觉(stereo vision)、抠图(Image matting)等,目前在医学图像领域应用较多。此类方法把图像分割问题与图的最小割(min cut)问题相关联。首先用一个无向图.G=<VE>表示要分割的图像,VE分别是顶点(vertex)和边(edge)的集合。此处的Graph和普通的Graph稍有不同。

 

        普通的图由顶点和边构成,如果边的有方向的,这样的图被则称为有向图,否则为无向图,且边是有权值的,不同的边可以有不同的权值,分别代表不同的物理意义。而Graph Cuts图是在普通图的基础上多了2个顶点,这2个顶点分别用符号”S”和”T”表示,统称为终端顶点。其它所有的顶点都必须和这2个顶点相连形成边集合中的一部分。所以Graph Cuts中有两种顶点,也有两种边。

 

      第一种顶点和边是:第一种普通顶点对应于图像中的每个像素。每两个邻域顶点(对应于图像中每两个邻域像素)的连接就是一条边。这种边也叫n-links

 

       第二种顶点和边是:除图像像素外,还有另外两个终端顶点,叫Ssource:源点,取源头之意)和Tsink:汇点,取汇聚之意)。每个普通顶点和这2个终端顶点之间都有连接,组成第二种边。这种边也叫t-links

 

       Graph Cuts中的Cuts是指这样一个边的集合,很显然这些边集合包括了上面2种边,该集合中所有边的断开会导致残留”S”和”T”图的分开,所以就称为“割”。如果一个割,它的边的所有权值之和最小,那么这个就称为最小割,也就是图割的结果。而福特-富克森定理表明,网路的最大流max flow与最小割min cut相等。所以由BoykovKolmogorov发明的max-flow/min-cut算法就可以用来获得s-t图的最小割。这个最小割把图的顶点划分为两个不相交的子集ST,其中s StTST=V 。这两个子集就对应于图像的前景像素集和背景像素集,那就相当于完成了图像分割。

 

       图像分割可以看成pixel labeling(像素标记)问题,目标(s-node)的label设为1,背景(t-node)的label设为0,这个过程可以通过最小化图割来最小化能量函数得到。那很明显,发生在目标和背景的边界处的cut就是我们想要的(相当于把图像中背景和目标连接的地方割开,那就相当于把其分割了)。同时,这时候能量也应该是最小的。假设整幅图像的标签label(每个像素的label)为L= {l1,l2,,,, lp },其中li0(背景)或者1(目标)。那假设图像的分割为L时,图像的能量可以表示为:

 

E(L)=aR(L)+B(L)

 

       其中,R(L)为区域项(regional term),B(L)为边界项(boundary term),而a就是区域项和边界项之间的重要因子,决定它们对能量的影响大小。如果a0,那么就只考虑边界因素,不考虑区域因素。E(L)表示的是权值,即损失函数,也叫能量函数,图割的目标就是优化能量函数使其值达到最小。

 

2.仿真效果预览

matlab2022a仿真结果如下:

 

 

 

 

3.MATLAB核心程序

 

clc;
clear;
close all;
warning off;
addpath(genpath(pwd));
 
%%
%参数初始化
%初始图像名称
I             = double(imread('Test_Image\hand.jpg'));
%迭代次数
iter          = 400;         
       
%初始模板,模板在初始的时候只要定义一个较大的矩阵即可
S1                       = size(I,1);
E1                       = size(I,2);
Es                       = 20;
MASK0                    = zeros(S1,E1);
MASK0(Es:S1-Es,Es:E1-Es) = 1;
 
%转换为二维图
if size(I,3) > 1
   Is = (I(:,:,1)+I(:,:,2)+I(:,:,3))/3;
else
   Is =  I;
end
 
[Result,Result2,Object] = func_Active_Contour_Flow(Is,I,MASK0,iter);
 
figure;
subplot(131);
imshow(uint8(I),[]);
hold on
contour(Result,[0,0],'r','linewidth',2); 
subplot(132);
imshow(Result2,[]);
subplot(133);
imshow(uint8(Object));
A107

 

  

 

posted @ 2023-02-15 15:54  我爱C编程  阅读(46)  评论(0编辑  收藏  举报