CGA填充算法之种子填充算法

CGA填充算法之种子填充算法

  平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界 (也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也可能是图案填充)。区域填充中最常用的是多边形填色,本文讨论种子填充算法(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的填充效果就认为“8-联通算法”一定比“4-联通算法”好,应该根据应用环境和实际的需求选择联通搜索方式,在很多情况下,只有“4-联通算法”才能得到正确的结果。

1. 注入填充算法(Flood Fill Algorithm)

  边界填充算法与注入填充算法的本质其实是一样的,都是递归和搜索,区别只在于对边界的确 认,也就是递归的结束条件不一样。注入填充算法没有边界的概念,只是对联通区域内指定的颜色进行替换,而边界填充算法恰恰强调边界的存在,只要是边界内的 点无论是什么颜色,都替换成指定的颜色。边界填充算法在应用上也非常的广泛,画图软件中的“油漆桶”功能就是边界填充算法的例子。以下就是边界填充算法的 一个实现:

void FloodSeedFill(int x, int y, int old_color, int new_color)
 {
     if(GetPixelColor(x, y) == old_color)
     {
          SetPixelColor(x, y, new_color);
          for(int i = 0; i < COUNT_OF(direction_8); i++)
          {
             FloodSeedFill(x + direction_8[i].x_offset,
             y + direction_8[i].y_offset, old_color, new_color);
           }
      }
}

   for循环实现了向8个联通方向的递归搜索,秘密就在direction_8的定义:

typedef struct tagDIRECTION
{
    int x_offset;
    int y_offset;
}DIRECTION;

    DIRECTION direction_8[] = { {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1} };

  下图就是应用本算法实现的“4-联通”和“8-联通”填充效果:

     

2. 边界填充算法(Boundary Fill Algorithm)

   边界填充算法与注入填充算法的本质其实是一样的,都是递归和搜索,区别只在于对边界的确认,也就是递归的结束条件不一样。注入填充算法没有边界的概念,只 是对联通区域内指定的颜色进行替换,而边界填充算法恰恰强调边界的存在,只要是边界内的点无论是什么颜色,都替换成指定的颜色。边界填充算法在应用上也非 常的广泛,画图软件中的“油漆桶”功能就是边界填充算法的例子。以下就是边界填充算法的一个实现:

void BoundarySeedFill(int x, int y, int new_color, int boundary_color)
{
    int curColor = GetPixelColor(x, y);
    if( (curColor != boundary_color)&& (curColor != new_color) )
    {
        SetPixelColor(x, y, new_color);
        for(int i = 0; i < COUNT_OF(direction_8); i++)
         {
                BoundarySeedFill(x + direction_8[i].x_offset,
                y + direction_8[i].y_offset, new_color, boundary_color);
          }
     }
}                

  关于direction_8的说明请参考上一节,图3就是应用本算法实现的“4-联通”和“8-联通”填充效果(其中颜色值是1的点就是指定的边界):

  

3. 边界填充算法(Boundary Fill Algorithm)

参考网址:

  http://blog.csdn.net/orbit/article/details/7323090

时间: 2024-10-06 18:49:36

CGA填充算法之种子填充算法的相关文章

[计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(一)

一.首先说明: 这是啥? —— 这是利用C#FORM写的一个用来演示计算机图形学中 ①Bresenham直线扫描算法(即:连点成线):②种子填充法(即:填充多边形):③扫描线填充法 有啥用? ——  无论是连点成线还是区域填充在高级编程中基本上都提供很高效的库函数来调用.这里拿出这些算法一方面有利于大家理解那些封装的函数底层是实现:另一方面是方便嵌入式TFT屏幕底层驱动开发时借鉴的. 是啥样? ——  如下面的操作,不言而喻. 二.进入正题: 2-1.直线的扫描转换 图形的扫描转换实质就是在光栅

Opencv图像识别从零到精通(24)------漫水填充,种子填充,区域生长、孔洞填充

可以说从这篇文章开始,就结束了图像识别的入门基础,来到了第二阶段的学习.在平时处理二值图像的时候,除了要进行形态学的一些操作,还有有上一节讲到的轮廓连通区域的面积周长标记等,还有一个最常见的就是孔洞的填充,opencv这里成为漫水填充,其实也可以叫种子填充,或者区域生长,基本的原理是一样的,但是应用的时候需要注意一下,种子填充用递归的办法,回溯算法,漫水填充使用堆栈,提高效率,同时还提供了一种方式是扫描行.经常用来填充孔洞,现在来具体看看. 漫水填充:也就是用一定颜色填充联通区域,通过设置可连通

种子填充算法

1 /************************************************************* 2 pb-图形学题4 3 种子填充算法 4 5 *************************************************************/ 6 7 8 #include <GL/glut.h> 9 #include<cstdio> 10 #include<cmath> 11 #include<stack

计算机图形学 - 扫描线种子填充算法

算法描述: 种子填充算法原理和程序都很简单, 但由于多次递归, 费时.费内存, 效率不高.为了减少递归次数, 提高效率可以采用扫描线种子填充算法.算法的基本过程如下: 当给定种子点( x, y) 时, 首先填充种子点所在扫描线上的位于给定区域的一个区段, 然后确定与这一区段相连通的上.下两条扫描线上位于给定区域内的区段, 并依次保存下来.反复这个过程, 直到填充结束. 区域填充的扫描线算法可由下列4 个步骤实现: ①  初始化: 堆栈置空.将种子点(x, y) 入栈. ② 出栈: 若栈空则结束.

多边形区域填充算法--递归种子填充算法

http://blog.csdn.net/orbit/article/details/7323090 平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界(也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也可能是图案填充).区域填充中最常用的是多边形填色,本文中我们就讨论几种多边形区域填充算法. 一.种子填充算法(Seed Filling) 如果要填充的区域是以图像元数据方式给出的,通常使用种子填充算法(Seed Fillin

UVA 572 -- Oil Deposits(DFS求连通块+种子填充算法)

UVA 572 -- Oil Deposits(DFS求连通块) 图也有DFS和BFS遍历,由于DFS更好写,所以一般用DFS寻找连通块. 下述代码用一个二重循环来找到当前格子的相邻8个格子,也可用常量数组或者写8条DFS调用. 下述算法是:种子填充(floodfill) 两种连通区域 四连通区域:从区域内一点出发,可通过上.下.左.右四个方向的移动组合,在不越出区域的前提下,能到达区域内的任意像素 八连通区域:从区域内每一像素出发,可通过八个方向,即上.下.左.右.左上.右上.左下.右下移动的

计算机图形学中的种子填充算法c++程序实现

种子填充其实很简单,计算机图形学中介绍的使用栈,感觉作者是不是脑子进水了,直接使用一个队列用广搜就可以了啊,但是我就懒得写了,直接一个递归算了,有兴趣的同学自己试一试 #include<graphics.h>#include<conio.h>  #include<stdio.h>#include<math.h>int Graph[500][500] ; void scanline_seed_fill(int color,int sx,int sy){ Gra

基于扫描种子线算法的多边形区域填充实现

本学期算法课上我们学习了计算几何的基础内容,在课后的深入了解学习中我发现,计算几何仅仅是算法世界一个重要分支——计算机图形学的基础部分之一,计算机图形学还有很多其他非常有趣的算法,例如直线生成.圆生成.椭圆生成.而在本学期进行java项目实践的过程中,我也遇到了一个和计算机图形学息息相关的问题,那就是如何实现windows自带画图软件中的工具油漆桶?网上的开源画图代码基本上均只实现了其他简单的绘制工具.为此,在查阅大量相关资料后,我学习到,种子填充算法可以很好地实现多边形区域填充,并用其中效果最

CGA裁剪算法之Sutherland-Hodgman多边形裁剪算法

CGA裁剪算法之Sutherland-Hodgman多边形裁剪算法 Sutherland-Hodgman算法也叫逐边裁剪法,该算法是萨瑟兰德(I.E.Sutherland)和霍德曼(Hodgman)在1974年提出的. 这种算法采用了分割处理.逐边裁剪的方法.这一算法,适合任何凸多边形窗口对任何“凸或者凹,或者平面或者非平面”多边形的裁剪处理. 逐边逐次裁剪特点:逐边是分别用裁剪平面的边界来处理,且裁剪各个边界的处理顺序无关紧要.逐次是每次的裁剪边界对多边形的每条边处理是依次进行的,有顺序要求.