简述边界表示的四连通区域的种子填充算法的基本思想和执行步骤

简述边界表示的四连通区域的种子填充算法的基本思想和执行步骤,第1张

一、种子填充算法思想:

首先填充种子所在的尚未填充搏哗的一区段,然后确定与这一区段相邻的上下两条扫描线上位于该区段内是否存在需要填充的新区段,如果存在,则依次把每个新区段最右端的象素作为种子放入堆栈。反复这个过程,直到堆栈为空。

二、种子填基庆行充算法差老步骤:

1、初始化堆栈。

2、种子压入堆栈。

3、While(堆栈非空)从堆栈d出种子象素。

有关图形窗口和图形屏幕 *** 作函数

一、图形窗口 *** 作

象文本方式下可以设定屏幕窗口一样,图形方式下也可以在屏幕上某一区域设定窗口,只是设定的为图形窗口而已,其后的有关图形 *** 作都将以这个窗口的左上角 (0, 0)作为坐标原点,而且可为通过设置使窗口之塌州外的区域为不可接触。这样,所有的图形 *** 作就被限定在窗口内进行。 void far setviewport(int xl,int yl,int x2, int y2,int clipflag)设定一个以(xl,yl)象元点为左上角,(x2,y2)象元为右下角的图

形窗口,其中x1,y1,x2,y2是相对于整个屏幕的坐标。若 clipflag为非0,则设定的图形以外部分不可接触,若clipflag为0,则图形窗口

以外可以接触。

void far clearviewport(void)清除现行图形窗口的内容。

void far getviewsettings(struct viewporttypefar * viewport)获得关于现行窗口的信息,并将其存于viewporttype定义的结构

变量viewport中,其中viewporttype的结构说明如下:

struct viewporttype

{

int left, top, right, bottom

int cliplag

}

注明:

1. 窗口颜色的设置与前面讲过的屏幕颜色设置相同,但屏幕背景色和窗口背景色只能是一种颜色,察旁如果窗口背景色改变,整个屏幕的背景色也将改变这与文本窗口不同。

2. 可以在同一个屏幕上设置多个窗口,但只能有一个现行窗口工作,要对其它窗口 *** 作,通过将定义那个窗口的setviewport()函数再用一次即可。

3. 前面讲过图形屏幕 *** 作的函数均适合于对窗口的 *** 作。

二、屏幕 *** 作

除了清屏函数以外,关于屏幕 *** 作还有以下函数:

void far setactivepage(int pagenum)void far setvisualpage(int pagenum)这两个函数只用于EGA,VGA 以及HERCULES图形适配器。 setctivepage()函数是为图形输出选择激活页。所谓激活页是指后续图形的输出被写到函数选定的 pagenum页面,该页面并不一定可见。

setvisualpage()函数才使pagenum所指定的页面变成可见页。页面从0开始(Turbo C默认页)。如果先用setactivepage() 函数在不同页面

上画出一幅幅图像,再用setvisualpage() 函数交替显示,就可以实现一些动画的效果。

void far getimage(int xl,int yl, int x2,int y2,void far *mapbuf)void far putimge(int x,int,y,void * mapbuf, int op)unsined far imagesize(int xl,int yl,int x2,int y2)

这三个函数用于将屏幕上的图像复制到内存,然后再将内存中的图像送回到屏幕上。首先通过函数imagesize() 测试要保存左上角为

(xl,yl),右上角为(x2,y2)的图形屏幕区域内的全部内容需多少个字节,然后再给mapbuf分配一个所测数字节内存空间的指针。通过调用

getimage()函数就可将该区域内的图像保存在内存中,需要时可用putimage()函数将该图像输出到左上角为点(x, y)的位置上,其中

getimage()函数中的参数op规定如何释放内存中图像。 关于这个参数的定义参见下表:

putimage()函数中的op值

━━━━━━━━━━━━━━━━━━━━━━━━━━

符号常数 数值 含 义

——————————————————————————

COPY_PUT 0 复制

XOR_PUT 1 与屏幕图像异或的复制

OR_PUT 2 与屏幕图像或后复制

AND_PUT 3 与屏幕图像与后复制

NOT_PUT 4 复制反像的图形团没蔽

━━━━━━━━━━━━━━━━━━━━━━━━━━

对于imagesize()函数,只能返回字节数小于64K字节的图像区域,否则将会出错,出错时返回-1。

本节介绍的函数在图像动画处理、菜单设计技巧中非常有用。

下面程序模拟两个小球动态碰撞过程。#include

#include

#include

int main()

{

int i, gdriver, gmode, size

void *buf

gdriver=DETECT

initgraph(&gdriver, &gmode, "c:\\caic\\bgi")

setbkcolor(BLUE)

cleardevice()

setcolor(LIGHTRED)

setlinestyle(0,0,1)

setfillstyle(1, 10)

circle(100, 200, 30)

floodfill(100, 200, 12)

size=imagesize(69, 169, 131, 231)

buf=malloc(size)

if(!buf) return -1

getimage(69, 169, 131, 231,buf)

putimage(500, 269, buf, COPY_PUT)

for(i=0i<185i++){

putimage(70+i, 170, buf, COPY_PUT)

putimage(500-i, 170, buf, COPY_PUT)

}

for(i=0i<185i++){

putimage(255-i, 170, buf, COPY_PUT)

putimage(315+i, 170, buf, COPY_PUT)

}

getch()

closegraph()

}

图形模式下的文本输出

在图形模式下,只能用标准输出函数,如printf(),puts(),putchar()函数输出文本到屏幕。除此之外,其它输出函数(如窗口输出函数)不能使用,即是可以输出的标准函数,也只以前景色为白色,按80列,25行的文本方式输出。

Turbo C2.0也提供了一些专门用于在图形显示模式下的文本输出函数。下面将分别进行介绍。

一、文本输出函数 void far outtext(char far *textstring)该函数输出字符串指针textstring所指的文本在现行位置。

void far outtextxy(int x, int y, char far *textstring)该函数输出字符串指针textstring所指的文本在规定的(x, y)位置。其中x和y为象元坐标。

说明:

这两个函数都是输出字符串,但经常会遇到输出数值或其它类型的数据,此时就必须使用格式化输出函数sprintf()。sprintf()函数的调用格式为: int sprintf(char *str, char *format, variable-list)它与printf()函数不同之处是将按格式化规定的内容写入str 指向的字符串中,返回值等于写入的字符个数。

例如:

'C110F1sprintf(s, "your TOEFL score is %d", mark)这里s应是字符串指针或数组,mark为整型变量。

二、有关文本字体、字型和输出方式的设置

有关图形方式下的文本输出函数,可以通过setcolor()函数设置输出文本的颜色。另外,也可以改变文本字体大小以及选择是水平方向输出还是垂直方向输出。

void far settexjustify(int horiz, int vert)该函数用于定位输出字符串。

对使用outtextxy(int x, int y, char far *str textstring)函数所输出的字符串,其中哪个点对应于定位坐标(x,y)在TurboC2.0中是有规定的。如果把一个字符串看成一个长方形的图形,在水平方向显示时,字符串长方形按垂直方向可分为顶部,中部和底部三个位置,水平方向可分为左,中,右三个位置,两者结合就有9个位置。

settextjustify()函数的第一个参数horiz 指出水平方向三个位置中的一个,第二个参数vert指出垂直方向三个位置中的一个,二者就确定了其中一个位置。当规定了这个位置后,用outtextxy () 函数输出字符串时,字符串长方形的这个规定位置就对准函数中的(x,y)位置。而对用outtext()函数输出字符串时,这个规定的位置就位于现行游标的位置。有关参数 horiz和vert的取值参见下表:

参数horiz和vert的取值

━━━━━━━━━━━━━━━━━━━━━━━━

符号常数 数值 用于

————————————————————————

LEFT_TEXT 0 水平

RIGHT_TEXT 2 水平

BOTTOM_TEXT 0 垂直

TOP_TEXT 2 垂直

CENTER_TEXT 1 水平或垂直

━━━━━━━━━━━━━━━━━━━━━━━━

void far settextstyle(int font, int direction,int charsize)

该函数用来设置输出字符的字形(由font确定)、输出方向(由direction确定)和字符大小(由charsize确定)等特性。

Turbo C2.0对函数中各个参数的规定见下列各表所示:

font的取值

━━━━━━━━━━━━━━━━━━━━━━━━

符号常数 数值 含义

————————————————————————

DEFAULT_FONT 0 8*8点阵字(缺省值)

TRIPLEX_FONT 1 三倍笔划字体

SMALL_FONT 2 小号笔划字体

SANSSERIF_FONT 3 无衬线笔划字体

GOTHIC_FONT 4 黑体笔划字

━━━━━━━━━━━━━━━━━━━━━━━━

direction的取值

━━━━━━━━━━━━━━━━━━━━━━━━

符号常数 数值 含义

————————————————————————

HORIZ_DIR 0 从左到右

VERT_DIR 1 从底到顶

━━━━━━━━━━━━━━━━━━━━━━━━

charsize的取值

━━━━━━━━━━━━━━━━━━━━━━━━

符号常数或数值 含义

————————————————————————

1 8*8点阵

2 16*16点阵

3 24*24点阵

4 32*32点阵

5 40*40点阵

6 48*48点阵

7 56*56点阵

8 64*64点阵

9 72*72点阵

10 80*80点阵

USER_CHAR_SIZE=0 用户定义的字符大小

━━━━━━━━━━━━━━━━━━━━━━━━

有关图形屏幕下文本输出和字体字型设置函数的用法请看下例:#include

#include

int main()

{

int i, gdriver, gmode

char s[30]

gdriver=DETECT

initgraph(&gdriver, &gmode, "c:\\caic\\bgi")

setbkcolor(BLUE)

cleardevice()

setviewport(100, 100, 540, 380, 1)

/*定义一个图形窗口*/

setfillstyle(1, 2)/*绿色以实填充*/

setcolor(YELLOW)

rectangle(0, 0, 439, 279)

floodfill(50, 50, 14)

setcolor(12)

settextstyle(1, 0, 8)

/*三重笔划字体, 水平放大8倍*/

outtextxy(20, 20, "Good Better")

setcolor(15)

settextstyle(3, 0, 5)

/*无衬笔划字体, 水平放大5倍*/

outtextxy(120, 120, "Good Better")

setcolor(14)

settextstyle(2, 0, 8)

i=620

sprintf(s, "Your score is %d", i)

/*将数字转化为字符串*/

outtextxy(30, 200, s)

/*指定位置输出字符串*/

setcolor(1)

settextstyle(4, 0, 3)

outtextxy(70, 240, s)

getch()

closegraph()

return 0

}

三、用户对文本字符大小的设置

前面介绍的settextstyle()函数,可以设定图形方式下输出文本字符这字体和大小但对于笔划型字体(除8*8点阵字以个的字体),只能在水平和垂直方向以相同的放大倍数放大。为此Turbo C2.0又提供了另外一个setusercharsize() 函数,对笔划字体可以分别设置水平和垂直方向的放大倍数。该函数的调用格式为:

void far setusercharsize(int mulx, int divx,int muly, int divy)该函数用来设置笔划型字和放大系数,它只有在settextstyle()

函数中的charsize为0(或USER_CHAR_SIZE)时才起作用,并且字体为函数settextstyle()规定的字体。调用函数 setusercharsize()后,每个显示在屏幕上的字符都以其缺省大小乘以mulx/divx为输出字符宽,乘以muly/divy为输出字符高。该函数的用法见下例:

#include

#include

int main()

{

int gdriver, gmode

gdriver=DETECT

initgraph(&gdriver, &gmode, "c:\\caic\\bgi")

setbkcolor(BLUE)

cleardevice()

setfillstyle(1, 2)/*设置填充方式*/

setcolor(WHITE)/*设置白色作图*/

rectangle(100, 100, 330, 380)

floodfill(50, 50, 14)/*填充方框以外的区域*/

setcolor(12)/*作图色为淡红*/

settextstyle(1, 0, 8)/*三重笔划字体,放大8倍*/

outtextxy(120, 120, "Very Good")

setusercharsize(2, 1, 4, 1)

/*水平放大2倍,垂直放大4倍*/

setcolor(15)

settextstyle(3, 0, 5)

/*无衬字笔划,放大5倍*/

outtextxy(220, 220, "Very Good")

setusercharsize(4, 1, 1, 1)

settextstyle(3, 0, 0)

outtextxy(180, 320, "Good")

getch()

closegraph()

return 0

}

一、种子填充算法(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)

注入填充算法不特别强调区域的边界,它只是从指定位置开始,将所有联通区域内某种指定颜色的点都替换成另一种颜色,从而实现填充效果。注入填充算法能够实现颜色替换之类的功能,这在图像处理软件中都得到了广泛的应用。注入填充算法的实现非常简单,核心就是递归和搜索,以下就是注入填充算法的一个实现:

164 void 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 = 0i <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的定义:

15 typedef struct tagDIRECTION

16 {

17 int x_offset

18 int y_offset

19 }DIRECTION

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

这个是搜索类算法中常用的技巧,无需做太多说明,其实只要将其替换成如下direction_4的定义,就可以将算法改成4个联通方向填充算法:

80 DIRECTION direction_4[] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} }

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


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12555874.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存