二值图像轮廓追踪算法

二值图像轮廓追踪算法

主要分为两个方面,一个是算法的原理,二是算法的代码实现。这里为了实现方便选用python来对算法进行实现。

一、算法原理

对于二值图像来说,其中每一个像素不是255就是0,这里假设背景为255,前景为0,即在图像中找到黑色物体的轮廓。
1、遍历二值图像找到其中某个黑像素,然后以此为开始点。
2、将开始的8邻域分为8个方向,先从0向开始,如果0向的为黑像素,则将该点设置为当前像素,否则将方向加一(顺时针转45度),继续判断,直到有黑像素,若八个方向全部遍历都没有黑像素,则当前的开始点放弃。
3、按照第二步找到的新的中心点,沿着第二步方向的逆时针90度的方向开始遍历新中心点的8邻域,操作同第二步。
4、对于新选中的中心点和开始点比较,如果相同,则证明已经找到了一个轮廓。
5、继续遍历二值图像,找到另一个开始点,重复2,3,4步操作。

二、python实现

def track(img_gray):
    h,w = img_gray.shape
    flag = False
    for row in range(h):
        for col in range(w):
            if img_gray[row][col] == 0:
                flag = t(img_gray,np.array([row,col]))
    show(flag)
def t(img,startP):
    direct = np.array([[-1,-1],[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1]])
    find = False
    currentP = startP
    currentD = 0
    dst = np.ones_like(img_gray) * 255
    while not find:
        for i in range(8):
            currentD = currentD%8
            currentP = currentP + direct[(currentD+i)%8]
            if img[currentP[0]][currentP[1]] == 0:
                currentD = currentD + i +6
                dst[currentP[0]][currentP[1]] = 0
                break

        if currentP[0] == startP[0] and currentP[1] == startP[1]:
            find =True
    return dst

在这段代码中track函数主要用来遍历二值图像,然后调用t函数找到轮廓。
t函数则为该算法的核心部分,主要完成了算法原理中2,3,4步。下面主要来说下t函数中的代码内容:
定义8邻域的方向,左上为0,顺时针增加。

direct = np.array([[-1,-1],[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1]])

其中find定义是否找到封闭轮廓,用来控制循环。初始当前点为开始点,初始搜索方向为0向,定义一个全白的图像,显示找到的路径信息。

find = False
currentP = startP
currentD = 0
dst = np.ones_like(img_gray) * 255

while循环中是算法迭代的具体流程,依照代码,来分析一下这个流程:
首先,没有找到闭合轮廓进入while循环之中。
然后利用for循环实现对8邻域的搜索。
在for循环中,方向有0-7八个方向,为了实现,方便循环实现,方向的选择,使用对8取余。
当前点记录八个邻域的点,然后在if中判断当前邻域点的值,如果等于0,就在dst中把当前邻域点设为0,其中currentD+i这是找到的搜索到邻域中0像素点的方向,下一次的搜索方向应该是逆时针90度,即方向减二,但会出现负值,所以改为加6,然后在对8取余,就实现了逆时针九十度的效果。
之后跳出当前的邻域搜索循环,使用if语句判断找到的点和开始点是否重合,如果重合,将find=True否则,利用新的点,继续邻域搜索循环,知道满足找到的点和开始点重合,跳出while循环。

while not find:
    for i in range(8):
        currentD = currentD%8
        currentP = currentP + direct[(currentD+i)%8]
        if img[currentP[0]][currentP[1]] == 0:
            currentD = currentD + i +6
            dst[currentP[0]][currentP[1]] = 0
            break

     if currentP[0] == startP[0] and currentP[1] == startP[1]:
         find =True

猜你喜欢

转载自blog.csdn.net/qq_25105061/article/details/108600967
今日推荐