在MS-Paint时代,我们都会画一些东西,然后用颜色填满它。这种任务属于区域填充(Seed-Fill)算法。
区域填充是对一个区域或图像进行填充的过程。根据填充方式的不同,它可以被分为以下几类。
- 边界填充算法--在相同像素值的边界内的区域
- 泛滥填充算法--具有相同像素值的区域
图1 淹没式填充算法
图2 边界填充算法
在这篇文章中,我们要讨论的是边界算法。
边界填充算法简介
在计算机图形学中,边界填充算法用于将边界为同一颜色的封闭多边形的内部填充为所需的颜色。它主要用于交互式绘画软件包,在那里可以很容易地选择一个内点,因为它的方法需要一个起始像素,也称为种子,以开始。
实施细节和问题陈述
它主要使用基于堆栈的递归来实现。边界填充的功能需要一个内部点(x,y)、填充颜色和边界颜色来开始。该算法首先检查一个像素的值是否等于边界颜色或填充颜色。如果不是,像素将被填充成所需的颜色,并继续检查邻近的像素。否则,不填。这个过程一直持续到它到达边界区域的所有边。
此外,边界填充算法可以用4个连接的像素和8个连接的像素来实现。
4
个
连接的像素:相邻的像素是在当前像素的左边、右边、上面和下面的像素。
图3 邻近像素
4连通与8连通
在有尖锐边界的情况下,4连通的方法失败了,而8连通的方法则有效地填充了该区域。下图代表了这种情况。
边界填充算法
边界填充算法的步骤。
-
有两种定义的颜色:边界的颜色(color_boundary)和需要填充的颜色(color_fill)。
-
获取当前像素的颜色(例如color1)。
-
如果color1等于color_boundary或color_fill,就不需要做什么,因为已经分配了正确的颜色。
-
如果color1不等于这两个值:
4.1.4.1. 在当前像素上添加 color_fill.
4.2.对4个相邻的像素点做同样的处理。(x, y-1), (x+1, y), (x, y+1), (x-1, y)
4.3.如果要做8个连接的填充,对4个对角线的像素点另外做同样的处理。(x+1, y-1), (x+1, y+1), (x-1, y+1), (x-1, y-1)。 -
对每一个像素点都做这个过程。
void boundary_fill(int x,int y,int fill_color,int boundary_color){
int cur_color = getpixel(x,y);
if(cur_color == boundary_color or cur_color == fill_color)
return;
fillpixel(x,y,fill_color);
boundary_fill(x,y-1,fill_color,boundary_color);
boundary_fill(x+1,y,fill_color,boundary_color);
boundary_fill(x,y+1,fill_color,boundary_color);
boundary_fill(x-1,y,fill_color,boundary_color);
/*For 8-connected pixels,additional calls
boundary_fill(x+1,y-1,fill_color,boundary_color);
boundary_fill(x+1,y+1,fill_color,boundary_color);
boundary_fill(x-1,y+1,fill_color,boundary_color);
boundary_fill(x-1,y-1,fill_color,boundary_color);
*/
}
边界填充算法的时间复杂度是O(N),其中N是像素的数量。
递归调用的空间复杂度为O(N)。在一个迭代实现中,空间复杂度将是O(1)。
限制条件
- 起点应该在封闭的多边形内。
- 对于一个多边形的所有边缘,边界颜色应该是相同的。
- 如果某些内部像素已经被填充了颜色,它可能无法填充。
通过OpenGenus的这篇文章,你一定对边界填充算法有了完整的了解。