实验三 区域填充算法的实现

合集下载

CG03区域填充

CG03区域填充

P6(2,7)
P4(11,8) F G C D P3(11,3) E 5 10 11
8 7
A
P5(5,5) B
P2(5,1)
P1(2,2)
0
1
一个多边形与若干扫描线
2. 边界上象素的取舍 对左下角为(1,1) ,在上角为(3,3)的 正方形填充时,若对边 界 上 所 有 象 素 均 进行填 充,就得到图2-8的的结 果 。 被 填 充 的 象 素复盖 的面积为3X3个单位,而 方形的实际面积只有2X2 个 单 位 。 为 了 克 服这个 问题,我们规定落在右/ 上边界的象素不予填充 ,而落在左/下边界的象 素予以填充。
边填充算法
基本原理:对于每一条扫描线和每条多 边形边的交点(x1,y1),将该扫描线上交点右 方的所有象素取补。如图。
边填充算法示意图
使用栅栏
为了减少边填充算法访问象素的次数,可引入栅栏。栅 栏指的是一条与扫描线垂直的直线,栅栏位置通常取过多边 形顶点、且把多边形分为左右两半。 栅栏填充算法的基本思想是:对于每个扫描线与多边形 边的交点,就将交点与栅栏之间的象素取补。若交点位于栅 栏左边,则将交点置右,栅栏之左的所有象素取补;若交点 位于栅栏的右边,则将交点置左,交点之左的象素取补。栅 栏填充算法只是减速少了被重复访问的角素的数目,但仍有 一些象素会被重复访问。
1. 首先构造一个纵向扫描线链表,链表的长 度为多边形所占有的最大扫描线数,链表 的每个结点称为桶,对应多边覆盖的每一 条扫描线。 2. 将每条边的信息链入与该最小y坐标(ymin) 相对应的桶处。 3. 对于每一条扫描线,如果新增多条边,则 按x|ymin坐标递增的顺序存放在一个链表 中,若x|ymin相等,则按照1/k由小到大排 序,这样就形成了边表。

区域填充算法范文

区域填充算法范文

区域填充算法范文
常见的区域填充算法有种子填充算法和扫描线填充算法。

种子填充算法是一种递归算法,从指定的种子点开始,将其颜色设为
目标颜色,并继续填充其相邻的像素点,直到所有相邻的像素点都被填充
为目标颜色。

这个过程可以通过递归或者使用栈进行实现。

种子填充算法
的优点是简单易懂,但对于复杂的区域存在堆栈溢出的风险。

扫描线填充算法利用了图形中连续的扫描线和区域的边界特性。

首先,确定区域的上下边界,然后对每一条扫描线从左往右进行遍历。

当扫描线
与区域的边界相交时,根据交点的颜色决定当前像素点的填充颜色。

该算
法可以通过判断相邻像素点的颜色是否相同来确定区域的边界。

为了提高算法的效率,可以使用填充算法的优化技术。

例如,使用堆
栈数据结构来存储需要填充的像素点,避免了递归过程中的堆栈溢出问题。

另外,可以使用四邻域或八邻域填充算法来决定像素点的相邻关系,减少
算法的时间复杂度。

总之,区域填充算法是图形学和图像处理中的重要算法之一,通过将
指定的区域填充为指定的颜色,实现了各种复杂任务的自动化处理和可视
化展示。

随着计算机技术的发展,区域填充算法的应用前景将会更加广泛,并且不断出现新的算法和优化技术,提高填充效率和质量。

计算机图形学 实验三 二维图形的区域填充

计算机图形学 实验三 二维图形的区域填充

西北农林科技大学实习报告学院名称:理学院专业班级:姓名:学号:课程:计算机图形学实验报告日期:第十四周实验三二维图形的区域填充一、实验目的1)加深对填充算法的理解,分析比较种子填充和边缘填充的差异。

2)掌握二维图形区域种子填充的原理和算法。

二、实验步骤1)对任意多边形的几何形状进行分析,选定比较合适的算法模型。

2)画出程序流程图;3)编写程序的源程序;4)编辑源程序并进行调试;5)进行特殊模式的运行测试,并结合情况进行调整。

三、实验内容用种子填充算法编写程序实现区域填充,并能在计算机上编译运行,正确地实现任意多边形边界的单色填充。

原理边界填充算法可以让用户首先勾画图的轮廓,选择填充颜色和填充模式,然后拾取内部点,系统就可以自动给图的内部涂上所需要的颜色和图案。

该算法的输入是种子点坐标 ( x , y )、填充色和边界颜色。

算法从( x , y )开始检测相邻位置是否是边界颜色,若不是,就用填充色着色,并检测其相邻位置。

该过程延续到已经检测完区域边界颜色范围内的所有像素为止。

使用栈结构来实现4-连通边界填充算法的算法步骤如下:(1)种子像素入栈。

(2)执行如下三步操作:1 栈顶像素出栈。

2 将出栈像素置成填充色。

3 检查出栈像素的4-邻接点,若其中某个像素不是边界色且未置成多边形色,则把该像素入栈。

(3)检查栈是否为空,若栈非空重复执行步骤(2),若栈为空则结束。

边界填充算法可以用于填充带有内孔的平面区域。

其缺点是把太多的像素压入堆栈,有些像素甚至会入栈多次,这样一方面降低了算法的效率,另一方面还要求很大的存储空间以实现栈结构。

将之改进,可构造沿扫描线填充水平像素段的4-连通边界填充算法,其算法步骤如下:(1)种子像素入栈。

(2)执行如下三步操作:1 栈顶元素出栈。

2 填充出栈元素所在扫描行的连续像素段,从出栈的像素开始沿扫描线向左和向右填充,直到遇到边界像素为止,即每出栈一个像素,就对包含该像素的整个扫描线区间进行填充,并且记录下此时扫描线区间的x坐标范围[ x1, x2 ]。

区域填充算法

区域填充算法

区域填充算法⼀、区域填充概念区域:指已经表⽰成点阵形式的填充图形,是象素的集合。

区域填充:将区域内的⼀点(常称种⼦点)赋予给定颜⾊,然后将这种颜⾊扩展到整个区域内的过程。

区域填充算法要求区域是连通的,因为只有在连通区域中,才可能将种⼦点的颜⾊扩展到区域内的其它点。

1、区域有两种表⽰形式1. 内点表⽰:枚举出区域内部的所有象素内部所有象素着同⼀个颜⾊边界像素着与内部象素不同的颜⾊。

2. 边界表⽰:枚举出区域外部的所有象素边界上的所有象素着同⼀个颜⾊内部像素着与边界象素不同的颜⾊。

2、区域连通1. 四向连通区域:从区域上⼀点出发可通过上、下、左、右四个⽅向移动的组合,在不越出区域的前提下,到达区域内的任意象素。

2. ⼋向连通区域:从区域上⼀点出发可通过上、下、左、右、左上、右上、左下、右下⼋个⽅向移动的组合,在不越出区域的前提下,到达区域内的任意象素。

3. 四连通与⼋连通区域的区别连通性:四连通可以看作⼋连通的⾃⼰,但是对边界有要求⼆、简单种⼦填充算法1、基本思想给定区域G⼀种⼦点(x, y),⾸先判断该点是否是区域内的⼀点,如果是,则将该点填充为新的颜⾊,然后将该点周围的四个点(四连通)或⼋个点(⼋连通)作为新的种⼦点进⾏同样的处理,通过这种扩散完成对整个区域的填充。

这⾥给出⼀个四连通的种⼦填充算法(区域填充递归算法),使⽤【栈结构】来实现原理算法原理如下:种⼦像素⼊栈,当【栈⾮空】时重复如下三步:2、算法代码这⾥给出⼋连通的种⼦填充算法的代码:void flood_fill_8(int[] pixels, int x, int y, int old_color, int new_color) { if (x < w && x > 0 && y < h && y > 0) {// 如果是旧的颜⾊⽽且还没有给他填充过if (pixels[y * w + x] == old_color) {// 填充为新的颜⾊pixels[y * w + x]== new_color);// 递归flood_fill_8(pixels, x, y + 1, old_color, new_color);flood_fill_8(pixels, x, y - 1, old_color, new_color);flood_fill_8(pixels, x - 1, y, old_color, new_color);flood_fill_8(pixels, x + 1, y, old_color, new_color);flood_fill_8(pixels, x + 1, y + 1, old_color, new_color);flood_fill_8(pixels, x + 1, y - 1, old_color, new_color);flood_fill_8(pixels, x - 1, y + 1, old_color, new_color);flood_fill_8(pixels, x - 1, y - 1, old_color, new_color);}}}3、OpenCV实现import cv2def seed_fill(img):ret, img = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY_INV) label = 100stack_list = []h, w = img.shapefor i in range(1, h-1, 1):for j in range(1, w-1, 1):if (img[i][j] == 255):img[i][j] = labelstack_list.append((i, j))while len(stack_list) != 0:cur_i = stack_list[-1][0]cur_j = stack_list[-1][1]img[cur_i][cur_j] = labelstack_list.remove(stack_list[-1])# 四邻域,可改为⼋邻域if (img[cur_i-1][cur_j] == 255):stack_list.append((cur_i-1, cur_j))if (img[cur_i][cur_j-1] == 255):stack_list.append((cur_i, cur_j-1))if (img[cur_i+1][cur_j] == 255):stack_list.append((cur_i+1, cur_j))if (img[cur_i][cur_j+1] == 255):stack_list.append((cur_i, cur_j+1))cv2.imwrite('./result.jpg', img)cv2.imshow('img', img)cv2.waitKey()if __name__ == '__main__':img = cv2.imread('./test.jpeg', 0)seed_fill(img)4、简单种⼦填充算法的优点和缺点优点:1. 该算法也可以填充有孔区域缺点:1. 有些像素会多次⼊栈,降低算法效率,栈结构占空间2. 递归执⾏,算法简单,但效率不⾼,区域内每⼀像素都要进/出栈,费时费内存3. 改进算法,减少递归次数,提⾼效率三、扫描线种⼦填充算法⽬标:减少递归层次适⽤于边界表⽰的4连通区间1、基本思想在任意不间断区间中只取⼀个种⼦像素(不间断区间指在⼀条扫描线上⼀组相邻元素),填充当前扫描线上的该段区间;然后确定与这⼀区段相邻的上下两条扫描线上位于区域内的区段,并依次把它们保存起来,反复进⾏这个过程,直到所保存的各个区段都填充完毕。

实验三指导书

实验三指导书

实验三区域填充与直线的裁剪1.实验目的:1)实现种子填充法或扫描线算法中的一种。

2)任选一种算法实现直线的裁剪。

2.实验内容:编写区域填充和直线裁剪的源程序,并能在计算机上编译运行,画出正确的图形。

3.实验步骤:1)对区域填充的几种算法进行理解;2)编程实现绘制多边形;3)对直线裁剪的几种算法进行理解;4)编程实现直线的裁剪;5)画出程序流程图;6)编写程序的源程序;7)编辑源程序并进行调试;8)进行特殊模式的运行测试,并结合情况进行调整。

9)打印源程序或把源程序以文件的形式提交。

4.实验报告:1)按格式书写实验报告;2)提交源程序文件或打印件。

算法描述区域填充1) 多边形由一系列首尾相连的直线段构成的图形称为多边形。

如果在多边形内任意选取不相同的两点,其连线上的所有点均在该多边形内,这样的多边形称为凸多边形;否则,称为凹多边形。

2) 种子填充算法种子填充算法又称为边界填充算法。

其基本思想是:从多边形区域的一个内点开始,由内向外用给定的颜色画点直到边界为止。

如果边界是以一种颜色指定的,则种子填充算法可逐个像素地处理直到遇到边界颜色为止。

种子填充算法常用四连通域和八连通域技术进行填充操作。

从区域内任意一点出发,通过上、下、左、右四个方向到达区域内的任意像素。

用这种方法填充的区域就称为四连通域;这种填充方法称为四向连通算法。

从区域内任意一点出发,通过上、下、左、右、左上、左下、右上和右下八个方向到达区域内的任意像素。

用这种方法填充的区域就称为八连通域;这种填充方法称为八向连通算法。

一般来说,八向连通算法可以填充四向连通区域,而四向连通算法有时不能填充八向连通区域。

例如,八向连通填充算法能够正确填充如图2.4a所示的区域的内部,而四向连通填充算法只能完成如图2.4b的部分填充。

四向连通填充算法a) 连通域及其内点b) 填充四连通域四向连通填充算法:a)种子像素压入栈中;b)如果栈为空,则转e);否则转c);c)弹出一个像素,并将该像素置成填充色;并判断该像素相邻的四连通像素是否为边界色或已经置成多边形的填充色,若不是,则将该像素压入栈;d)转b);e)结束。

实验三 区域填充原理

实验三 区域填充原理

实验三区域填充原理实验目的掌握二维区域填充的填充算法;实验环境计算机、Turbo C、C++等其他语言程序设计环境实验学时2学时,必做实验。

实验内容1.二维封闭区域的种子填充算法和扫描线种子填充算法;2.熟悉多边形扫描线填充算法;内点表示四连通种子填充算法(漫水法)参考代码:#include<graphics.h>void floodfill4(int x,int y,int oldcolor,int newcolor){if(getpixel(x,y)==oldcolor){putpixel(x,y,newcolor);delay(20000);floodfill4(x,y+1,oldcolor,newcolor);floodfill4(x,y-1,oldcolor,newcolor);floodfill4(x-1,y,oldcolor,newcolor);floodfill4(x+1,y,oldcolor,newcolor);}}main(){int a,b,c,d,i,j;int graphdriver=DETECT, graphmode=0;initgraph(&graphdriver,&graphmode," ");cleardevice();setcolor(14);rectangle(100,100,150,150);for(i=101;i<150;i++)for(j=101;j<150;j++){ putpixel(i,j,4);delay(1000);}a=120; b=110; c=4; d=2;floodfill4(a,b,c,d);getch();closegraph();}边界表示的4连通区域的种子填充算法:#include<stdio.h>;#include<graphics.h>;void BoundaryFill4(int x,int y,int boundarycolor,int newcolor) {if(getpixel(x,y)!=boundarycolor&getpixel(x,y)!=newcolor) {putpixel(x,y,newcolor);delay(20000);BoundaryFill4(x,y+1,boundarycolor,newcolor);BoundaryFill4(x,y-1,boundarycolor,newcolor);BoundaryFill4(x-1,y,boundarycolor,newcolor);BoundaryFill4(x+1,y,boundarycolor,newcolor);}}main() {int a,b,c=14,d,i,j;int graphdriver=DETECT,graphmode=0;initgraph(&graphdriver,&graphmode," ");cleardevice();setcolor(c);rectangle(100,100,150,150);for(i=101;i<150;i++)for(j=101;j<150;j++) { putpixel(i,j,4); delay(1000); } a=120; b=130; d=2;BoundaryFill4(a,b,c,d);getch();closegraph();}扫描线种子填充算法参考代码:#include<graphics.h>#include<stdio.h>#include<stdlib.h>#define bordercolor 15#define backcolor 0#define seedcolor 4#define fillcolor 10typedef struct Point{int x;int y;}point;typedef struct Stack{point *base;point *top;}*stack;void initstack(stack s){(*s).base=(point*)malloc(sizeof(point));if(!(*s).base)exit(1);(*s).top=(*s).base;}void push(stack s,point p){*((*s).top)=p;(*s).top++;}int stackempty(stack s){if((*s).top==(*s).base)return(1);else return(0);}point pop(stack s){(*s).top--;return(*((*s).top));}void drawgraphics(){int a[10]={100,140,260,80,300,200,160,240,100,140}; drawpoly(5, a);/*circle(200,200,150);*/}point produceseed(){point p;p.x=200;p.y=200;return(p);}void intostack(stack s,int y0,int xl,int xr){int x,y;point tm;for(x=xl,y=y0;x<=xr&&x<getmaxx();x++){if((x!=xr&&getpixel(x,y)==backcolor&&getpixel(x+1,y)!=backcolor)||(x==xr&&getpixel(x,y)==backcolor)){tm.x=x;tm.y=y;push(s,tm);putpixel(x,y,seedcolor);}if(x==xr&&getpixel(x,y)==backcolor)break;}}void fillgraphics(){int xl=0,xr=getmaxx(),x,y;point seed;stack s=NULL;seed=produceseed();putpixel(seed.x,seed.y,seedcolor);getch();initstack(s);push(s,seed);while(!stackempty(s)){seed=pop(s);for(x=seed.x,y=seed.y;getpixel(x,y)==backcolor||getpixel(x,y)==seedcolor;x++) {putpixel(x,y,fillcolor);}xr=x-1;for(x=seed.x-1,y=seed.y;getpixel(x,y)==backcolor||getpixel(x,y)==seedcolor;x--) {putpixel(x,y,fillcolor);}xl=x+1;intostack(s,seed.y+1,xl,xr);intostack(s,seed.y-1,xl,xr);getch();}}void main(){int gdriver ,gmode ;gdriver = DETECT;initgraph(&gdriver , &gmode ,"" );drawgraphics();fillgraphics();outtextxy(180,20,"Scan line filling graphics finished!"); getch();closegraph();}多边形扫描线填充算法参考代码:/* Note:扫描线填充算法*/#include <graphics.h>#include <conio.h>#include <math.h>#define MAXPOINT 20typedef struct {int y_top;float x_int;int delta_y;float x_cps;}E_ENTRY;void putin_sl(int entry,int x1,int y1,int x2,int y2,int next_y); void sortonby(int n);void updatefl(int count,int scan);void swap(E_ENTRY *x,E_ENTRY *y);void sortonx(int entry,int first_s);void processx(int first_s,int last_s);void drawline(int scan,int x_int_c,int index);void updatesl();E_ENTRY sides[MAXPOINT];int x[MAXPOINT]={0,210,240,230,350,380,340,200,180,150}; int y[MAXPOINT]={0,410,370,200,410,340,140,180,120,300}; int s_count,first_s,last_s,scan,bottom_s,x_int_c;main(){int driver,mode;int v_count=9;driver=DETECT;initgraph(&driver,&mode,"");setcolor(3);fillarea(v_count,x,y);getch();closegraph();}fillarea(int count){sortonby(count);first_s=1;last_s=1;for(scan=sides[1].y_top;scan>bottom_s;scan--){updatefl(count,scan);processx(first_s,last_s);drawline(scan,x_int_c,first_s);updatesl();}}void putin_sl(int entry,int x1,int y1,int x2,int y2,int next_y) {int maxy;float x2_temp,xch_temp;xch_temp=(float)(x2-x1)/(float)(y2-y1);x2_temp=x2;if((y2>y1)&&(y2<next_y)){y2--;x2_temp-=xch_temp;}else{if((y2<y1)&&(y2>next_y)){y2++;x2_temp+=xch_temp;}}maxy=(y1>y2)?y1:y2;while((entry>1)&&(maxy>sides[entry-1].y_top)){sides[entry]=sides[entry-1];entry--;}sides[entry].y_top=maxy;sides[entry].delta_y=abs(y2-y1)+1;if(y1>y2)sides[entry].x_int=x1;elsesides[entry].x_int=x2_temp;sides[entry].x_cps=xch_temp;}void sortonby(int n){int k,x1,y1;s_count=0;y1=y[n];x1=x[n];bottom_s=y[n];for(k=1;k<n+1;k++){if(y1!=y[k]){s_count++;putin_sl(s_count,x1,y1,x[k],y[k],y[k+1]);}else{/* line((short)x1,480-(short)y1,(short)x[k],480-(short)y1);*/moveto((short)x1,480-(short)y1);lineto((short)x[k],480-(short)y1);}if(y[k]<bottom_s) bottom_s=y[k];y1=y[k];x1=x[k];}}void updatefl(int count,int scan){while((sides[last_s+1].y_top>scan)&&(last_s<count))last_s++;while(sides[first_s].delta_y==0) first_s++;}void swap(E_ENTRY *x,E_ENTRY *y){int i_temp;float f_temp;i_temp=x->y_top;x->y_top=y->y_top;y->y_top=i_temp;f_temp=x->x_int;x->x_int=y->x_int;y->x_int=f_temp;i_temp=x->delta_y;x->delta_y=y->delta_y;y->delta_y=i_temp;f_temp=x->x_cps;x->x_cps=y->x_cps;y->x_cps=f_temp;}void sortonx(int entry,int first_s){while((entry>first_s)&&(sides[entry].x_int<sides[entry-1].x_int)) {swap(&sides[entry],&sides[entry-1]);entry--;}}void processx(int first_s,int last_s){int k;x_int_c=0;for(k=first_s;k<last_s+1;k++){if(sides[k].delta_y>0){x_int_c++;sortonx(k,first_s);}}}void drawline(int scan,int x_int_c,int index){int k,x,x1,x2;for(k=1;k<(int)(x_int_c/2+1.5);k++){while(sides[index].delta_y==0)index++;x1=(int)(sides[index].x_int+0.5);index++;while(sides[index].delta_y==0)index++;x2=(int)(sides[index].x_int+0.5);/*line((short)x1,480-(short)scan,(short)x2,480-(short)scan);*/ moveto((short)x1,480-(short)scan);lineto((short)x2,480-(short)scan);index++;}}void updatesl(){int k;for(k=first_s;k<last_s+1;k++){if(sides[k].delta_y>0){sides[k].delta_y--;sides[k].x_int-=sides[k].x_cps;}}}。

区域填充算法

区域填充算法

区域填充算法填充原理种⼦填充算法是从区域内任⼀个种⼦像素位置开始,由内向外将填充⾊扩散到整个多边形区域的填充过程。

种⼦填充算法突出的优点是能对具有任意复杂闭合边界的区域进⾏填充。

四邻接点与⼋邻接点四连通域与⼋连通域种⼦填充算法算法定义从种⼦像素点开始,使⽤四邻接点⽅式搜索下⼀像素点的填充算法称为四邻接点填充算法。

从种⼦像素点开始,使⽤⼋邻接点⽅式搜索下⼀像素点的填充算法称为⼋邻接点填充算法。

⼋邻接点填充算法的设计和四邻接点填充算法基本相似,只要把搜索⽅式由四邻接点修改为⼋邻接点即可。

算法原理种⼦填充算法⼀般要求区域边界⾊和填充⾊不同,输⼊参数只有种⼦坐标位置和填充颜⾊。

种⼦填充算法⼀般需要使⽤堆栈数据结构来实现。

先将种⼦像素⼊栈,种⼦像素为栈底像素,如果栈不为空,执⾏如下3步操作:1. 栈顶像素出栈;2. 按填充颜⾊绘制出栈像素。

3. 按左、右、下、上(或左、左上、上、右上、右、右下、下、左下)顺序搜索与出栈像素相邻的四(⼋)个像素,若该像素的颜⾊不是边界⾊并且未置成填充⾊,则把该像素⼊栈;否则丢弃该像素。

该算法也可以填充有孔区域。

缺点:递归执⾏,算法简单,但效率不⾼,区域内每⼀象素都引起⼀次递归,进/出栈,费时费内存。

改进算法,减少递归次数,提⾼效率。

解决⽅法是⽤扫描线填充算法。

扫描线算法⽬标:减少递归层次算法思想:在任意不间断区间中只取⼀个种⼦像素(不间断区间指在⼀条扫描线上⼀组相邻元素),填充当前扫描线上的该段区间;然后确定与这⼀区段相邻的上下两条扫描线上位于区域内的区段,并依次把它们保存起来,反复进⾏这个过程,直到所保存的个区段都填充完毕。

扫描线种⼦填充算法算法原理为:先将种⼦像素⼊栈,种⼦像素为栈底像素,如果栈不为空,执⾏如下4步操作。

1. 栈顶像素出栈。

2. 沿扫描线对出栈像素的左右像素进⾏填充,直⾄遇到边界像素为⽌。

即每出栈⼀个像素,就对区域内包含该像素的整个连续区间进⾏填充。

3. 同时记录该区间,将区间最左端像素记为xleft,最右端像素记为xright。

区域填充算法的实现

区域填充算法的实现

区域填充算法的实现实现区域填充算法的一种常见方法是使用递归。

以下是一个使用递归实现的区域填充算法的伪代码:1. 定义函数fillPixel(x, y, targetColor, fillColor):-如果像素点(x,y)的颜色与目标颜色相同,将其颜色修改为填充颜色。

-否则,返回。

2. 定义函数regionFill(x, y, targetColor, fillColor):-如果像素点(x,y)的颜色与目标颜色相同,返回。

- 否则,调用fillPixel(x, y, targetColor, fillColor)。

- 递归调用regionFill(x-1, y, targetColor, fillColor)。

- 递归调用regionFill(x+1, y, targetColor, fillColor)。

- 递归调用regionFill(x, y-1, targetColor, fillColor)。

- 递归调用regionFill(x, y+1, targetColor, fillColor)。

3. 调用regionFill(seedX, seedY, targetColor, fillColor)。

在上述算法中,fillPixel函数用于将特定颜色填充到像素点(x, y)。

regionFill函数使用递归的方式遍历相邻的像素点,并对目标颜色的像素点调用fillPixel函数。

seedX和seedY表示种子像素点的坐标,targetColor表示目标颜色,fillColor表示填充颜色。

实现区域填充算法时还需要考虑以下几个问题:1.像素点的表示:图像可以由二维数组表示,其中每个元素表示一个像素点的颜色。

2.填充颜色选择:填充颜色可以由RGB值表示,或者在预定义的颜色集合中选择。

3.边界处理:对于位于图像边界上的种子像素点,需要特殊处理以防止数组越界错误。

4.递归终止条件:填充算法使用递归,需要定义递归终止的条件,以防止无限递归。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验三区域填充算法的实现
一、实验目的和要求:
1、掌握区域填充算法基本知识
2、理解区域的表示和类型,能正确区分四连通和八连通的区域
3、了解区域填充的实现原理,利用Microsoft Visual C++ 6.0或win-TC实现区
域种子填充的递归算法。

二、实验内容:
1、编程完成区域填色
2、利用画线函数,在屏幕上定义一个封闭区域。

3、利用以下两种种子填充算法,填充上述步骤中定义的区域
(1)边界表示的四连通区域种子填充的实现
(2)内点表示的四连通区域种子填充的实现
4、将上述算法作部分改动应用于八连通区域,构成八连通区域种子填充算法,
并编程实现。

三、实验结果分析
四连通图的实现:
程序代码:
#include<graphics.h>
#include <conio.h>
#include<math.h>
#include<time.h>
void BoundaryFill4(int x,int y,int Boundarycolor,int newcolor)
{
if(getpixel(x,y) != newcolor && getpixel(x,y) !=Boundarycolor)
{
putpixel(x,y,newcolor);
Sleep(1);
BoundaryFill4(x-1,y,Boundarycolor,newcolor);
BoundaryFill4(x,y+1,Boundarycolor,newcolor);
BoundaryFill4(x+1,y,Boundarycolor,newcolor);
BoundaryFill4(x,y-1,Boundarycolor,newcolor);
}
}
void polygon(int x0,int y0,int a,int n,float af)
{
int x,y,i;
double dtheta,theta;
if(n<3)
return;
dtheta=6.28318/n;
theta=af*0.0174533;
moveto(x0,y0);x=x0;y=y0;
for(i=1;i<n;i++)
{
x=x+a*cos(theta);y=y+a*sin(theta);
lineto(x,y);theta=theta+dtheta;
}
lineto(x0,y0);
}
void main()
{
int x=50,y=75;
int a,b,c,d,i,j;
int graphdriver=DETECT;
int graphmode=0;
initgraph(&graphdriver,&graphmode," ");
cleardevice();
setcolor(RGB(0,255,0));
setfillstyle(WHITE);
polygon(x,y,60,5,0.);
a=100;
b=100;
c=RGB(0,255,0);
d=RGB(255,0,255);
BoundaryFill4(a,b,c,d);
getch();
closegraph();}
实验结果
八连通的实现
程序代码:
#include<graphics.h>
#include<conio.h>
#include<time.h>
#include <malloc.h>
#include <windows.h>
#define MaxSize 100
typedef struct{
int x;
int y;
}Seed,ElemType;
typedef struct
{
ElemType data[MaxSize];
int top; //栈顶指针
} SqStack;
void InitStack(SqStack *&s)
{
s=(SqStack *)malloc(sizeof(SqStack));
s->top=-1;
}
int StackEmpty(SqStack *s)
{
return(s->top==-1);
}
int Push(SqStack *&s,ElemType e)
{
if (s->top==MaxSize-1)
return 0;
s->top++;
s->data[s->top]=e;
return 1;
}
int Pop(SqStack *&s,ElemType &e)
{
if (s->top==-1)
return 0;
e=s->data[s->top];
s->top--;
return 1;
}
void floodfill8(int x,int y,int oldcolor,int newcolor) {
if(getpixel(x,y)==oldcolor)
{
putpixel(x,y,newcolor);
Sleep(2);
floodfill8(x,y+1,oldcolor,newcolor);
floodfill8(x,y-1,oldcolor,newcolor);
floodfill8(x-1,y,oldcolor,newcolor);
floodfill8(x+1,y,oldcolor,newcolor);
floodfill8(x+1,y+1,oldcolor,newcolor);
floodfill8(x+1,y-1,oldcolor,newcolor);
floodfill8(x-1,y+1,oldcolor,newcolor);
floodfill8(x-1,y-1,oldcolor,newcolor);
}
}
void main()
{
int a,b,c,d,i,j;
int graphdriver=DETECT;
int graphmode=0;
initgraph(&graphdriver,&graphmode," "); cleardevice();
setfillstyle(RGB(255,255,255));
setcolor(GREEN);
int points[]={320,200,270,290,370,290}; fillpoly(3,points);
rectangle(500,420,100,100);
a=RGB(255,255,255);
b=RGB(255,0,0);
floodfill8(320,240,a,b);
c=RGB(0,0,0);
d=RGB(0,0,255);
floodfill8(320,180,c,d);
getch();
closegraph();
}
实验结果:
2、结果分析:
通过以上各算法运行结果分析与对比可知:
1.四连通算法的缺点是有时不能通过狭窄区域,因而不能填满多边形。

2.八连通算法的缺点是有时会填出多边形的边界。

3.由于填不满往往比涂出更易于补救,因此四连通算法比八连通算法用的更多。

相关文档
最新文档