总结的动力来自于叶老师的灵魂拷问:下次我问你,你能讲出来吗?

那必须的~~

Trapped-Ball Region Segmentation

陷球分割技术的提出:《Vectorizing Cartoon Animations》

之前看到的两篇上色论文都提到了这个技术,把图像分割成了不同颜色的色块,方便解决上色过程中的颜色溢出问题。但是都没有详细介绍过处理的过程,所以我理论梳理一下。

整体来说,它是借助一个半径为R的球形形态结构元件对图片进行处理,且半径不断修改,处理也越来越细致。

FloodFill

首先对原图进行洪水填充法上色:由某个像素点开始向四周扩散,以该点的像素值作为参考,设定像素值的上下限,在像素范围内的像素点将被纳入集合中,最终确定待上色的点集合,并对它们的颜色统一更新。

比如说,我的起始点在(x,y)(x, y),其像素值是68,而我设置的上下限分别为+22,28+22, -28,所以颜色区间为[40,90][40,90]。确定区间后就可以进行颜色填充了,从起始点开始,把四周像素值在区间内的颜色都修改成目标颜色。

有个前提,填充之前会有一个mask,也就是像线稿这样的黑白掩膜。上色时不能跨线条边界的。

引入一个opencv的FloodFill函数,以像素高低值判断填充区域:

1
2
3
4
5
6
7
img = cv2.imread('cat.jpg')
cv2.imshow('img',img)
mask = np.zeros([img.shape[0]+2,img.shape[1]+2],np.uint8) #+2是使用要求
#floodfill的参数:1.操作图像 2.掩膜 3.起始像素点 4.填充颜色 5.填充颜色的低值 6.填充颜色的高值 7.填充方法
cv2.floodFill(img,mask,(30,30),(255,100,100),(20,20,20),(50,50,50),cv2.FLOODFILL_FIXED_RANGE)
cv2.imshow('newimg',img)
cv2.waitKey()

在这里插入图片描述

Trapped-ball filling

当确定一个大致的区域之后,我们就希望尽可能准确细致地进行图像分割。因为有时候掩膜的线条有缺漏,结果导致上色上多了。比如对a进行洪水填充,因为线条是断断续续的,所以导致四个块都成了蓝色,但实际上,我们更希望分成4个颜色不同的块。

因此进行洪水填充后,对c这张去掉mask后的结果图进行形态学处理。使用半径为R的球形形态结构元件进行图像处理中的侵蚀操作,保留下了一个面积尽可能大的三角块d,接着再进行膨胀操作,扩大填充面积得到图e,这就是第一次trapped-ball filling的结果。

总结一下,这个方法可以把该区域内的像素值都设置为另一个新值,并通过特定规则来实现区域内点中连通区域,进而对相似区域进行填充,直到找到区域内所有像素或边界轮廓为止。没有被更新的区域,是因为它表现出了不同的特征。

Repeat

重复FloodFill和Trapped-ball filling的过程,就能对整张图处理,最后得到多种颜色的粗略分割图。

被修改过颜色的区域,可以设置为visited,下一次处理从未访问过的像素点开始进行填充。

dilation

关于上面提到的dilation操作,我们首先要确定小球半径的大小。理论上,半径越小,覆盖的区域就越精确。但是实际上,如果碰到上图这样线段有缺漏的图,就会导致颜色泄漏。而如果一开始确定的半径太大,又会造成训练次数的增加。

所以,可以选择设置一个下限半径,进行一个小球半径逐渐递减的dilation操作。

color

在整个filling的过程中,目标颜色是程序给的,也就是借助某个函数得到的。

挂一篇上色论文的处理过程图