Lazysnapping Grabcut 算法实现的结果

8月8号到8月18号,根据Lazysnapping的论文和一些资料,做了算法实现但是前期处理和LS不同, 其实不算真正实现LS。

有人用通俗易懂的话这样解释:

首先,当一张图被导入到Lazy snapping中时,软件会自动采用watershed对该图进行处理。接下来,用户通过划线,确定F和B。如果从像素点的角度来看,一旦画了一条线,则这条线经过的像素点被称为“种子点”,这些“种子点”所涉及到的区域被称为“种子区域”。借助这些“种子区域”将图片分为F 和B 。利用Graph Cut优化算法,图片上所有区域会被赋予惟一的属性,不属于“前景区域”就一定会属于“背景区域”。在经过处理后的图片中,相邻的区域连接在一起。而接下来Graph Cut优化算法要做的,就是尝试将每个非“种子区域”分别与“前景区域”(或“背景区域”)之间的通路“打断”。如果全部通路都可以被打断,则软件猜测该区域不属于F,则可能属于B。也就将我们所需要的前景的大致轮廓勾勒了出来。Graph Cut 优化的准则,考虑了每一个区域的颜色与种子区域之间的颜色相似性,颜色越像“前景区域”就越可能被分在前景。同时它也考虑了相邻区域的颜色差别,颜色差别越大这两个区域越可能被分开。这个优化问题可以用图论中极大流(极小割)的方法很快解决。

实质上就是图像里面将问题转换成最大流最小割问题。 主要是将前景设置为sink 也就是终点, 背景设置为source 源。中间点 根据它们离前景和背景的每个像素点的颜色差值 来设置流入和流出权重,离前景越近 流入的权重越多 流出的权重越少。每条边的值 是与颜色差成反比,两个点颜色越不相似,值越小,也就是容积越小。 这个是GrabCut的本质 因为LS的关键是将Grabcut和预处理进行了很好的结合,将速度提升了。而这一步,我是没做的。

傻乎乎的写完之后 ,才弄清楚。。。。哎 回头有空用opencv里的资源再实现一次。

基本框架来自于 的源码,thx

他的和原文的差别主要在 GraphCut的预处理 是通过降低像素来进行,原文用了watershed来初分割。

其次,原文不是用平均距离来计算 该点到F其他点的距离,,而是将F中的点进行64的kmeans聚类,然后寻找其中最小的距离点。

再次,E2的计算方法不同。

然后改进根据gimp的开源代码进行了改进

lzhj的程序 分割 出来会有许多零碎区域,但是如果在计算E1时,加入kmeans聚类,则 这样的 区域会减少很多。

而对E2的修正 能够 很好的提升结果。

采用一些小小的技巧,可以使得算法不一定要背景笔 也能得到目标分割

算法前期处理改进可以有两个方面,meanshift 和watershed。

前期处理测试watershed floodfilled 但不知为啥 效果不佳,估计哪里出了点小错。没继续修改了,最后加入Meanshift结合金字塔算法对图像进行平滑,平滑前用floodfilled算法 很难获取比较大的区域,平滑后,如果目标不是很复杂,是可以获取整个目标区域的。

将用gimp测试图跑的结果放上来:

为了速度快,我将图压缩了,所以会有一点锯齿。

如果没有这个需求 可以跑出很精致的图的。

生气是拿别人做错的事来惩罚自己

Lazysnapping Grabcut 算法实现的结果

相关文章:

你感兴趣的文章:

标签云: