基于SLIC算法实现比PS魔棒还方便的抠图工具

最近给公司画板工具调研一个“抠图工具”,方便小朋友创作的时候快速抠图,效果图如下:

一.抠图的各种方案及优缺点对比

1.魔棒

(1)这个应该是最常见的抠图方式了
也找了个类似的前端开源项目(GitHub搜索Magic-Matting)
效果如下

(2)实测后发现这个效果并不好
需要很有耐心的慢慢的调节抠图范围(也有可能是算法参数我没有调好

2.两笔抠图

(1)最终采用的方案,效果图见本文第一张动图
(2)同类产品,如“稿定抠图”,也是绘制两笔
一笔前景色,一笔别景色,实现快速抠图
(3)对比
我这个方案是纯前端实现的抠图,不需要后端,也就是断网的情况下也能实现抠图,这一点是稿定抠图不能实现的。而且稿定抠图并没有提供抠图的接口,他的其他服务都是限量或者付费的。

二.SLIC超像素算法简介

1.论文地址

http://www.kev-smith.com/papers/SLIC_Superpixels.pdf

摘要如下:
近年来,计算机视觉应用越来越依赖超像素,但并不总是清楚什么是良好的超像素算法。为了解现有方法的优点和缺点,我们比较了目前最好的五种超像素算法,比较的指标为图像边界的粘附性,算法速度,存储效率,以及它们对分割性能的影响。然后我们介绍一种新的超像素算法,简单的线性迭代聚类(SLIC),它采用k均值聚类方法高效地生成超像素。尽管它很简单,但SLIC较以前的算法可以更好地获取边界,同时,它具有更快的速度,更高的内存效率,并且能提高分割性能,也可以直接扩展到超体元生成。

关键词-超像素,分割,聚类,k均值。

2.基本思想

SLIC算法是simple linear iterative cluster的简称,该算法用来生成超像素(superpixel)

算法大致思想是这样的,将图像从RGB颜色空间转换到CIE-Lab颜色空间,对应每个像素的(L,a,b)颜色值和(x,y)坐标组成一个5维向量V[L,a,b,x,y],两个像素的相似性即可由它们的向量距离来度量,距离越大,相似性越小。

算法首先生成K个种子点,然后在每个种子点的周围空间里搜索距离该种子点最近的若干像素,将他们归为与该种子点一类,直到所有像素点都归类完毕。然后计算这K个超像素里所有像素点的平均向量值,重新得到K个聚类中心,然后再以这K个中心去搜索其周围与其最为相似的若干像素,所有像素都归类完后重新得到K个超像素,更新聚类中心,再次迭代,如此反复直到收敛。怎么样,是不是感觉很像K-means聚类算法。

该算法接受一个参数K,用于指定生成的超像素数目。设原图有N个像素,则分割后每块超像素大致有N/K个像素,每块超像素的边长大致为S=[N/K]^0.5,开始我们每隔S个像素取一个聚类中心,然后以这个聚类中心的周围2S2S为其搜索空间,与其最为相似的若干点即在此空间中搜寻。这里有一个问题,为了避免所选的聚类中心是边缘和噪声这样的不合理点,算法做了改进, 在33的窗口中将聚类中心移动到梯度最小的区域,梯度定义为

G(x,y)=[V(x+1,y)-V(x-1,y)]^2+[V(x,y+1)-V(x,y-1)]^2

这样就可以避免上面所说的情况。

因为L,a,b在CIE-Lab颜色空间,L,a,b的大小有限制,而图像尺寸则没有限制,如果图片的尺寸比较大,会造成衡量向量距离时空间距离(x,y)的影响过大,所以需要调制空间距离(x,y)的影响,所以需要对x,y进行normalize。改进向量距离的度量如下:

d_lab=[(Lk-Li)^2+(ak-ai)^2+(bk-bi)^2]^0.5
d_xy=[(Xi-Xk)^2+(Yk-Yi)^2]^0.5
Ds=d_lab+(m/S)*d_xy

m用来调整d_xy的权值,一般为1-20,在算法中设置为10。
最后可能出现一些小的区域d被标记为归属某一块超像素但却与这块超像素没有连接,这就需要把这块小区域d重新归类为与这块小区域d连接的最大的超像素中去,以保证每块超像素的完整。

3.算法流程

下面仓库提供了SLIC的js实现
具体项目中还需要配合FabricJS或者Paperjs来实现交互操作哦~

GitHub: GitHub链接
欢迎小伙伴们star 💗❤️💖~~

同时欢迎关注我的个人微信公众号:

分享到:
Disqus 加载中...

如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理