Python实现图形学种子填充算法

算法原理

        采用了种子填充算法,种子填充算法的原理比较简单。

        即在多边形内选取一个起始点,从这个起始点出发,可选取上下左右四个方向前进,若前进的方向不是多边形的边界,则前进到该像素点,填充上新颜色后,再以此点位起始点,不断递归上述过程,知道碰到多边形边界。(有点像深度优先算法)。

算法步骤

1)先定义一个二维矩阵,定义所有的像素的为0

a=np.zeros((450,450))

2)利用我之前做过的DDA算法,将多边形的边绘制出来。同时将边所经过的像素点都记为2(即边界点)。

draw(0, 40, 40, 0)
draw(40, 0, 80, 40)
draw(0, 40, 60, 60)
draw(60, 60, 80, 40)
a[int(round(x))][int(round(y))] = 2

得到未填充的多边形

3)编写种子填充算法,参数x,y为当前起始点,先判断当前起始点是否是边界,如果不是,则将该点记为1(即填充点),同时上下左右四个点代入递归。

# 种子填充算法
def seedFill(x, y):
    if(a[x][y] == 0):
        a[x][y] = 1
        if(a[x+1][y] == 0):
            seedFill(x+1, y)
        if(a[x][y+1] == 0):
            seedFill(x, y+1)
        if(a[x-1][y] == 0):
            seedFill(x-1, y)
        if(a[x][y-1] == 0):
            seedFill(x, y-1)

4)至此,我们已经在二维矩阵中有了以下信息,0表示空白区域,1表示填充点,2表示边界点。

根据矩阵值的不同,绘制出不同颜色的点,完成填充。

#     在矩阵a中,0表示空白点,1表示填充点,2表示边界点
#     根据矩阵中值的不同来填充
    for i in range(0, 82):
        for j in range(0, 80):
            if(a[i][j] == 1):
                plt.plot(i, j, 'r.', markersize = 1)
            elif(a[i][j] == 2):
                plt.plot(i, j, 'b.', markersize = 1)

算法结果

1.填充前

2.填充后

 

 

算法源码

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import MaxNLocator
np.set_printoptions(threshold=np.inf)
# 初始化450*450的矩阵为零
a=np.zeros((450,450))
# 种子填充算法
def seedFill(x, y):
    if(a[x][y] == 0):
        a[x][y] = 1
        if(a[x+1][y] == 0):
            seedFill(x+1, y)
        if(a[x][y+1] == 0):
            seedFill(x, y+1)
        if(a[x-1][y] == 0):
            seedFill(x-1, y)
        if(a[x][y-1] == 0):
            seedFill(x, y-1)
# DDA直线扫描算法,用于绘制多边形的边界
def DDA(x1, y1, x2, y2):
    dx, dy = x2 - x1, y2 - y1
    k = dy/dx
    x, y = x1, y1
    #网格线
    plt.grid()
    #x轴y轴数值取整
    plt.gca().xaxis.set_major_locator(MaxNLocator(integer=True))
    plt.gca().yaxis.set_major_locator(MaxNLocator(integer=True))
    #绘点
    for i in range(0, int(abs(dx)+1)):
        #需要四舍五入
        plt.plot(int(round(x)), int(round(y)), 'b.', markersize = 1)
        a[int(round(x))][int(round(y))] = 2
        x += 1
        y += float(k)
# 绘制多边形的边
def draw(x, y, xEnd, yEnd):
    if xEnd < x:
        x,y, xEnd, yEnd = xEnd, yEnd, x, y
    DDA(x, y, xEnd, yEnd)
# 绘制多边形
def drawLine():
    draw(0, 40, 40, 0)
    draw(40, 0, 80, 40)
    draw(0, 40, 60, 60)
    draw(60, 60, 80, 40)
    #网格线
    plt.grid()
    plt.show()
    
if __name__ == '__main__':
    a[1][1]=1
    drawLine()
    #网格线
    plt.grid()
#     选取(40,18)作为种子起始点
    seedFill(40,18)
#     在矩阵a中,0表示空白点,1表示填充点,2表示边界点
#     根据矩阵中值的不同来填充
    for i in range(0, 82):
        for j in range(0, 80):
            if(a[i][j] == 1):
                plt.plot(i, j, 'r.', markersize = 1)
            elif(a[i][j] == 2):
                plt.plot(i, j, 'b.', markersize = 1)

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值