平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界(也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也可能是图案填充)。区域填充中最常用的是多边形填色,本文中我们就讨论几种多边形区域填充算法。
一、种子填充算法(Seed Filling)
如果要填充的区域是以图像元数据方式给出的,通常使用种子填充算法(Seed Filling)进行区域填充。种子填充算法需要给出图像数据的区域,以及区域内的一个点,这种算法比较适合人机交互方式进行的图像填充操作,不适合计算机自动处理和判断填色。根据对图像区域边界定义方式以及对点的颜色修改方式,种子填充又可细分为几类,比如注入填充算法(Flood Fill Algorithm)、边界填充算法(Boundary Fill Algorithm)以及为减少递归和压栈次数而改进的扫描线种子填充算法等等。
所有种子填充算法的核心其实就是一个递归算法,都是从指定的种子点开始,向各个方向上搜索,逐个像素进行处理,直到遇到边界,各种种子填充算法只是在处理颜色和边界的方式上有所不同。在开始介绍种子填充算法之前,首先也介绍两个概念,就是“4-联通算法”和“8-联通算法”。既然是搜索就涉及到搜索的方向问题,从区域内任意一点出发,如果只是通过上、下、左、右四个方向搜索到达区域内的任意像素,则用这种方法填充的区域就称为四连通域,这种填充方法就称为“4-联通算法”。如果从区域内任意一点出发,通过上、下、左、右、左上、左下、右上和右下全部八个方向到达区域内的任意像素,则这种方法填充的区域就称为八连通域,这种填充方法就称为“8-联通算法”。如图1(a)所示,假设中心的蓝色点是当前处理的点,如果是“4-联通算法”,则只搜索处理周围蓝色标识的四个点,如果是“8-联通算法”则除了处理上、下、左、右四个蓝色标识的点,还搜索处理四个红色标识的点。两种搜索算法的填充效果分别如如图1(b)和图1(c)所示,假如都是从黄色点开始填充,则“4-联通算法”如图1(b)所示只搜索填充左下角的区域,而“8-联通算法”则如图1(c)所示,将左下角和右上角的区域都填充了。
图(1) “4-联通”和“8-联通”填充效果
并不能仅仅因为图1的填充效果就认为“8-联通算法”一定比“4-联通算法”好,应该根据应用环境和实际的需求选择联通搜索方式,在很多情况下,只有“4-联通算法”才能得到正确的结果。
1.1 注入填充算法(Flood Fill Algorithm)
注入填充算法不特别强调区域的边界,它只是从指定位置开始,将所有联通区域内某种指定颜色的点都替换成另一种颜色,从而实现填充效果。注入填充算法能够实现颜色替换之类的功能,这在图像处理软件中都得到了广泛的应用。注入填充算法的实现非常简单,核心就是递归和搜索,以下就是注入填充算法的一个实现:
164void FloodSeedFill(int x, int y, int old_color, int new_color)
165{
166 if(GetPixelColor(x, y) == old_color)
167 {
168 SetPixelColor(x, y, new_color);
169 for(int i = 0; i < COUNT_OF(direction_8); i++)
170 {
171 FloodSeedFill(x + direction_8[i].x_offset,
172 y + direction_8[i].y_offset, old_color, new_color);
173 }
174 }
175}
|
for循环实现了向8个联通方向的递归搜索,秘密就在direction_8的定义:
15typedef struct tagDIRECTION
16{
17 int x_offset;
18 int y_offset;
19}DIRECTION;
|
79DIRECTION direction_8[] = { {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1} }; |
这个是搜索类算法中常用的技巧,无需做太多说明,其实只要将其替换成如下direction_4的定义,就可以将算法改成4个联通方向填充算法:
80DIRECTION direction_4[] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} }; |
图2就是应用本算法实现的“4-联通”和“8-联通”填充效果:
图(2) 注入填充算法实现
1.2 边界填充算法(Boundary Fill Algorithm)
边界填充算法与注入填充算法的本质其实是一样的,都是递归和搜索,区别只在于对边界的确认,也就是递归的结束条件不一样。注入填充算法没有边界的概念,只是对联通区域内指定的颜色进行替换,而边界填充算法恰恰强调边界的存在,只要是边界内的点无论是什么颜色,都替换成指定的颜色。边界填充算法在应用上也非常的广泛,画图软件中的“油漆桶”功能就是边界填充算法的例子。以下就是边界填充算法的一个实现:
177void BoundarySeedFill(int x, int y, int new_color, int boundary_color)
178{
179 int curColor = GetPixelColor(x, y);
180 if( (curColor != boundary_color)
181 && (curColor != new_color) )
182 {
183 SetPixelColor(x, y, new_color);
184 for(int i = 0; i < COUNT_OF(direction_8); i++)
185 {
186 BoundarySeedFill(x + direction_8[i].x_offset,
187 y + direction_8[i].y_offset, new_color, boundary_color);
188 }
189 }
190}
|
关于direction_8的说明请参考上一节,图3就是应用本算法实现的“4-联通”和“8-联通”填充效果(其中颜色值是1的点就是指定的边界):
图(3) 边界填充算法实现
<下一篇:扫描线种子填充算法>
分享到:
相关推荐
总结来说,多边形区域填充算法是计算机图形学中的核心技术,包括扫描线填充、种子填充、递归填充、边标志填充等多种方法,每种都有其适用场景和优缺点。通过深入理解和掌握这些算法,我们可以更好地实现复杂的图形...
种子填充算法(非递归)和多边形扫描算法是计算机图形学中的核心算法,用于在二维或三维空间中填充像素或三角形区域。这两种算法在游戏开发、图像处理、虚拟现实等领域有着广泛的应用。 首先,种子填充算法,也称为...
2. **Flood Fill算法**:这种算法从一个起始点开始,检查相邻的像素,如果它们满足填充条件(即在多边形内部),则改变这些像素的颜色并递归地对相邻像素进行填充。对于多边形填充,通常会从一个已知在多边形内的点...
种子填充算法,又称为扫描线填充算法,其基本思想是从一个或多个人工指定的“种子”点开始,通过判断像素与多边形边界的关系来递归地填充内部区域。以下是对种子填充算法的详细解释: 1. **种子点选择**:首先,...
区域填充算法是计算机图形学中的一个基础且重要的概念,它主要应用于图像处理、绘图软件以及游戏开发等领域。这种算法的目的是将用户在屏幕上画出的多边形或选定的像素区域染上特定的颜色,使得视觉效果更加完整和...
"Android 多边形区域递归种子填充算法的示例代码" 本文主要介绍了Android多边形区域递归种子填充算法的示例代码,通过对算法的详细分析和代码实现,提供了一个详细的示例代码,帮助开发者更好地理解和应用该算法。 ...
种子填充算法通过找到一个多边形内部的一个起始像素(即“种子”),然后递归地填充所有与其相邻的、且属于同一多边形区域的像素。这种方法适用于封闭的多边形,并依赖于连通性来确定哪些像素应该被填充。 #### ...
《算法设计英文版课件:Chapter 4 The Divide-and-Conquer Strategy》 Chapter 4的主题是分治策略,这是一种在计算机算法设计中极其重要的方法。分治策略的基本思想是将一个大问题分解为两个或多个相同或相似的小...
- **扫描线算法**:通过水平线遍历来填充区域,适用于多边形填充。 总的来说,递归填充算法在MFC工程中是一种实用的技术,能够帮助开发者高效地填充二维图形。通过理解其工作原理和在MFC中的具体实现,我们可以更...
Flood Fill算法是一种递归或队列驱动的方法,通常从用户指定的种子点开始,检查相邻像素,如果相邻像素颜色与种子点相同则跳过,否则将其颜色设为新颜色,并继续检查其相邻像素,直至整个区域填充完毕。 4. **...
本文将深入探讨“扫描算法转换多边形”以及“种子区域填充”这两种技术,它们在Visual C++(vc)环境中常被用到。 首先,让我们了解一下扫描线算法。扫描线算法的基本思想是将屏幕视为水平的扫描线,然后逐行处理...
接下来是种子填充算法,它是一种自底向上、递归的填充方式。通常从用户点击的一个种子点开始,通过检查相邻像素的颜色是否与种子点相同来决定是否填充。具体步骤包括: 1. 用户选择一个种子点,该点被认为是填充...
四连通递归填充算法基于递归的思想,从一个种子像素开始,检查其上下左右四个邻近像素是否属于待填充的区域,并将这些符合条件的像素颜色更改为指定的填充颜色,直到整个区域都被正确填充。这里的“四连通”指的是...
它的工作原理是首先将多边形边界投影到一系列水平线上,然后对这些线上的每个交点进行处理,将它们之间的区域填充颜色。具体步骤如下: 1. **边界检测**:确定多边形的边界顶点,并按Y坐标排序。 2. **生成扫描线段...
常用的区域填充算法包括扫描线算法和种子填充算法。 ##### 3. 程序结构解析 给定的代码示例展示了如何在一个MFC应用程序中实现一种填充算法。代码主要分为两部分:`FillApplyView.cpp` 和 `Fill2.cpp`。 - **...
扫描线算法首先将多边形沿Y轴分解成一系列水平线段,然后对每条线段上的点进行填充。在Android中,可使用两个优先级队列分别存储y值最小和最大的边,然后按顺序处理这些边,进行填充。 4. **活性边表算法**...
边界填充算法(Boundary Fill Algorithm)是一种常见的填充方法,其基本思想是从一个种子点开始,沿着多边形的边界向内填充颜色。主要有以下步骤: 1. **种子点选择**:在多边形内部选择一个点作为填充的起点。 2....
本篇文章将详细讲解两种主要的填充算法:扫描线区域填充和种子填充,这两种方法在图形处理和游戏开发等领域中有着广泛的应用。 **扫描线区域填充算法** 扫描线区域填充算法基于平面分割的思想,通过将屏幕划分为...
种子填充算法是一种常用的计算机图形学算法,它用于填充多边形区域的内部颜色。该算法的基本思想是从多边形区域的一个点开始,由向外画点直到边界为止。如果边界是以一种颜色指定的,那么种子填充算法可逐个像素地...