|
||||||||||||||||||||||
|
||||||||||||||||||||||
|
|||||
| Visual Basic编程疑难问题解(二)四 | |||||
| 作者:佚名 教程来源:不详 点击数: 更新时间:2006-5-29 | |||||
|
If ((imagepixels(0, p, q) = red1) And (imagepixels(1, p, q) = green1) And (imagepixels(2, p, q) = blue1)) Then imagepixels(0, p, q) = 0: imagepixels(2, p, q) = 0: imagepixels(1, p, q) = 0 Picture1.PSet (p, q), RGB(0, 0, 0) Call area(p + 1, q): Call area(p, q + 1) Call area(p - 1, q): Call area(p, q - 1) Call area(p + 1, q + 1): Call area(p + 1, q - 1) Call area(p - 1, q + 1): Call area(p - 1, q - 1) Else: Exit Sub End If End Sub 三、算法的基本思想 本算法采用两个队列(FIFO)filled和unfilled来实现区域填充。设计步骤如下: 1. 找出该区域内部任意一点,作为填充种子。 2. 填充该点,并把该点存入队列filled。 3. 按逆时针,判断该点的上、右、下、左邻像素是否在filled队列内。如果在filled,说明该相邻点已填充,若不在filled队列内,则判断该相邻点在未填充队列unfilled,如果不在则将该相邻点存入unfilled。 4. 判断未填充队列是否为空,若不空,则从队列unfilled中取出头元素,转向第三步。若为空则表示已完成所有像素填充,结束程序。 四、程序实现及说明 本算法定义的队列突破了递归算法中受堆栈空间大小的限制的束缚,因为它直接占用内存空间,与堆栈大小无关。以下源程序在Window 2000环境下用VB6.0编程实现。 建立如图所示标准窗体并画上控件-2个CommandButton控件和一个PictureBox控件,调整大小,并设置控件的属性。 通用声明 Dim Xx As Integer, Yy As Integer Dim Array1(9000, 2), Array2(9000, 2) As Integer 4.2 采集 Private Sub Command1_Click() Picture1.MousePointer = 2 End Sub 4.3 选取种子 Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) Xx = X '选择并记录种子点的位置 Yy = Y End Sub 4.4 区域填充 Private Sub Command2_Click() Dim i, j, k As Integer, BoundPoint1, BoundPoint2 As Integer Dim Flag As Boolean, Pixel As Long Dim Red, Green, Blue As Integer, Bound As Boolean Flag = True '初始化 i = Xx: j = Yy: BoundPoint1 = 1 Array1(1, 1) = i Array1(1, 2) = j '搜索边界点 Do While BoundPoint1 > 0 BoundPoint2 = 0 For k = 1 To BoundPoint1 i = Array1(k, 1) j = Array1(k, 2) '搜索右点 Pixel& = Picture1.Point(i, j + 1) Call IsBound(Pixel&, Bound) If Not Bound Then BoundPoint2 = BoundPoint2 + 1 Array2(BoundPoint2, 1) = i Array2(BoundPoint2, 2) = j + 1 Picture1.PSet (i, j + 1), RGB(255, 255, 255) End If '搜索左邻点 Pixel& = Picture1.Point(i, j - 1) Call IsBound(Pixel&, Bound) If Not Bound Then BoundPoint2 = BoundPoint2 + 1 Array2(BoundPoint2, 1) = i Array2(BoundPoint2, 2) = j - 1 Picture1.PSet (i, j - 1), RGB(255, 255, 255) End If '搜索上邻点 Pixel& = Picture1.Point(i - 1, j) Call IsBound(Pixel&, Bound) If Not Bound Then BoundPoint2 = BoundPoint2 + 1 Array2(BoundPoint2, 1) = i - 1 Array2(BoundPoint2, 2) = j Picture1.PSet (i - 1, j), RGB(255, 255, 255) End If '搜索下邻点 Pixel& = Picture1.Point(i + 1, j) Call IsBound(Pixel&, Bound) If Not Bound Then BoundPoint2 = BoundPoint2 + 1 Array2(BoundPoint2, 1) = i + 1 Array2(BoundPoint2, 2) = j Picture1.PSet (i + 1, j), RGB(255, 255, 255) End If Next k '数组array2 中的数据传给array1 BoundPoint1 = BoundPoint2 For k = 1 To BoundPoint1 Array1(k, 1) = Array2(k, 1) Array1(k, 2) = Array2(k, 2) Next k Picture1.Refresh Loop End Sub Public Sub IsBound(P As Long, Bound As Boolean) '判断P是否为边界点 Red = P& Mod 256 Bound = False Green = ((P& And &HFF00) / 256&) Mod 256& Blue = (P& And &HFF0000) / 65536 If Red = 255 And Green = 255 And Blue = 255 Then Bound = True End If End Sub 五、结束语 本算法实现了在对填充区域的形状、大小均未知的情况下,以种子点开始向四周对该区域进行“扩散式”的填充。本算法解决了传统的递归算法在填充较大区域时(本例中填充区约9800Pixels)堆栈溢出的缺点。我们的实验结果显示,本算法就填充区域大小和运算速度而言,都远远超过了传统的递归算法。 |
|||||
|
|||||
| 教程录入:dping 责任编辑:dping | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关教程 | ||
| windows vista好用吗?是不是 怎么将数字证书和签名加入到 请问装vista系统不打开特效后 我的电脑是华硕A6T 装了VIST C盘是VISTA D盘是XP 最后装的 信息系统工程师--SystemAdmi 关于windows update 安装WINDOWS VISTA的最低系统 请教XP和VISTA的区别! 为什么按右键总是出现symant |
网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |