实现SLIC算法生成像素画 (2)

205.png

当m越大,颜色空间除以m后的值越小,即空间距离的权重越大,生成的像素会更为形状规则,当m越小,颜色距离权重更大,超像素会在边缘更为紧凑,而形状大小较为不规则。

像素点分类。

标记每个像素点的类别为距离其最小的聚类中心的类别。

重新计算聚类中心。

计算属于同一个聚类的所有像素点的*均向量值,重新得到聚类中心 。

迭代4~6的过程。

直到旧聚类中心与新聚类中心的距离小于一定阈值或者达到一定迭代次数,一般来说,当迭代次数到达10,算法能够达到收敛。

聚类优化。

迭代到最后,可能会出现与聚类中心不属于同一连通域的孤立像素点,可以使用到连通算法将其分配到最*的聚类标签。

论文中并未给出具体的实现算法。而本文的应用场景是生成像素画,会对像素进行下取样,并不会细化到每个像素,由此,本文不做聚类优化处理。

实现SLIC算法生成像素画

小小总结一下,SLIC算法流程大体与K-means是一致的,不断迭代计算距离最小的聚类簇,不同的是只对聚类中心的S距离内像素点进行计算,减少了不少的计算量。

生成像素画

基于SLIC算法,我们已经可以把一张图划分为N个超像素点。每个超像素中像素都是相*的。也就是说,每个像素都被归类为一个超像素,有一个聚类中心。那么将像素的颜色赋值为其聚类中心的颜色即得到我们想要的效果。

设定一定步长stride,使用Canvas,每隔stride个像素,将像素赋值为其聚类中心的颜色,即得到最终的像素化结果。

实现SLIC算法生成像素画

而每个人对于像素画的主观感受是不一致的,为了让用户有更多的选择,得到自己满意的结果。可以暴露更多的人工干预参数,比如取消聚类优化的终止条件,改为由用户来设置迭代次数,以及最终取像素值的步长。人工设定的参数包括了

超像素点大小blocksize;blocksize越小,超像素点分割越细腻。

迭代次数iters;iters越大,分割结果更精准,计算时间越长。

颜色空间权重weight;weight越大,颜色对于分割结果的影响越大。

取像素点步长stride;stride越小,生成的像素图越接*超像素点,也就越细腻。

实现用户交互界面

作为一个工具,自然需要用户交互界面,前端界面基于HTML/Javascript/CSS搭建,使用Canvas API绘制图像内容,而用户交互面板选择的是dat.gui [3] 库。dat.gui是一个轻量级的图像化界面库,非常适用于参数的修改,常用作可视化 Demo 的演示。支持的参数类型包括了Number、String、Boolean、自定义函数等。可以为不同的属性绑定相应的响应事件,当属性值改变时自动触发事件。

为生成像素化工具添加以下属性与事件:

当iters、stride、blockSize、weight(颜色空间权重m)参数变化时重新进行SLIC算法的计算,并重新绘制计算结果;

添加Upload image 与Export image按钮,支持用户上传图片与下载像素化后的图片;

在绘制图像的Canvas画布层上叠加一层Canvas画布,对算法的结果进行可视化,添加以下功能

grid开关控制是否绘制像素网格;

Centers开关控制是否显示聚类中心;

Contours开关控制是否显示聚类边缘轮廓;

实现SLIC算法生成像素画

其中聚类中心点Centers的绘制直接使用ctx.fillRect 传入中心点坐标即可。

超像素轮廓Contours的绘制则需要先计算得到轮廓点。

可以对每个像素点与周围的8个像素点进行比较,如果聚类中心不同的像素点个数大于2,则代表着这个像素点周围有两个以上不同类别的点,则这个点为轮廓。效果如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjjff.html