图分割算法 ——概述

先说下写这篇文章的初衷,首先是为了记录我科研的一些笔记,其次呢是我在网上查阅图分割问题的时候,发现很难找到合适的讲解,基本都被图像处理的知识所占据。但并不是每个人都会有时间去查阅论文,所以就写下这篇博客来填补这方面的空白,谢谢诸位看官

一,图分割

定义:指将网络顶点分割为指定规模,指定数量的非重叠群组,并使得群组之间的边数最小

算法背景:实际上在图挖掘领域最早出现的问题就是图分割,当社团发现问题出现以后科学家首先使用图分割算法来发现社团,但后来渐渐放弃了。原因就是图分割算法有以下的局限:

1,需要事先指定分割的子图规模以及个数

2,一般的图分割算法,只会将图分割成两个子图,如果想获得多个子图那么需要不断的进行二分

二,问题定义

 简单的说就是,在一个无向有权图中,将图划分成若干个子图,并且使得子图之间的割边的权值和最大。对于这样一个NP难的问题,科学家很自然的想到了使用启发式算法来解决。

三,算法说明

1,数学描述

问题的解决思路很简单,就是先随机产生两个划分,计算他们的cost,然后通过一些操作是这个cost不断下降,达到最优解,注意这里的最优解明显是局部的,但是论文作者说这个局部解很有可能也是全局,这个问题我们咱不讨论;因为很多情况,局部最优解也是很优秀的解,而且启发式算法很容易避免局部最优解的问题。

那么如何进行所谓的“操作”呢?

在两路图分割问题中:A,B是初始的两个划分,通过交换内部的点或者集合,形成新的划分,并在算法的指导下,使划分的cost下降,逐渐逼近最优解;现在问题的解决思路基本明晰了,问题转化为在A,B中挑选X,Y

我简单翻译一下,作者定义了三个变量E,I,D分别代表着某点的外部cost,内部cost,和内外部cost之差,并证明了一个定理,如果交换两个点,会对总的cost产生什么样的影响,就是这个gain,显然接下来我们要控制这个gain向下降的方向变化。

2,算法简述

我们先用自然语言描述这个过程,第一步计算出全集里所有元素的D值,第二步在划分A,B中选择a1,b1进行交换并计算gain值,第三步对于A,B中的其他元素进行计算D值;接下来重复第二步,用{A-a1}和{B-b1}替换A,B,再计算gain'值,直到所有节点都被使用。每做一步就将gain值保存起来,并使得 \large G=\sum gain_{i},我们通过选择算法执行的步数K,来优化参数G,当G>0的时候,说明通过内部交换可以降低G值,算法继续执行;当G=0,我们便到达了局部最优点。以下就是算法的执行过程

 

算法过程中有几个判断需要着重讲一下,一是p=n?二是G>0?

在第一个判断中,集合的总数是2n,n是等大图划分中一半的节点数,也是我们程序的迭代最大次数;在第二个判断中,我们求得k值使得G值最大,接下来交换1至k的节点,然后继续迭代,直到G<=0才终止。

此部分的代码移步https://github.com/mcavus/Kernighan-Lin

对于不等大图的划分,目前来解决这个问题的一种主流方法,就是添加哑元素,来使两个集合的数量相同。

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 10
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
Opencv中的分水岭算法(watershed algorithm)是一种自动分割算法,常用于分离像中的前景和背景。下面是使用Opencv中的分水岭算法进行分割的步骤: 1. 读入像并进行预处理,如去噪、灰度化等。 2. 对像进行二值化处理,得到前景和背景的二值像。 3. 对二值像进行距离变换(distance transform),得到每个像素离最近的背景像素的距离。 4. 对距离变换后的像进行阈值处理,得到像的分水岭标记(watershed markers)。 5. 对分水岭标记进行修正,确保标记不会重叠或出现空洞。 6. 对分水岭标记应用分水岭算法,得到分割后的像。 下面是使用Opencv实现分水岭算法的示例代码: ```python import cv2 import numpy as np # 读取像并进行预处理 img = cv2.imread('input.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # 进行距离变换 dist_transform = cv2.distanceTransform(thresh,cv2.DIST_L2,5) ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0) # 获取分水岭标记 sure_fg = np.uint8(sure_fg) unknown = cv2.subtract(thresh,sure_fg) ret, markers = cv2.connectedComponents(sure_fg) markers = markers+1 markers[unknown==255] = 0 # 修正分水岭标记 markers = cv2.watershed(img,markers) img[markers == -1] = [255,0,0] # 显示分割结果 cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这段代码中,我们首先读入一张像并进行预处理,然后进行距离变换,得到每个像素到最近的背景像素的距离。接着使用阈值处理得到分水岭标记,修正分水岭标记并应用分水岭算法,最后显示分割结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值