美文网首页每周一赞
目标轮廓提取之边界跟踪法

目标轮廓提取之边界跟踪法

作者: 大龙10 | 来源:发表于2023-09-04 14:38 被阅读0次

    一、边界跟踪法

    • 边界跟踪
      定义为从图像中的一个边界点出发,然后根据某种判别准则搜索出下一个边界点,以此跟踪出目标边界。

    二、边界跟踪的一般步骤

    • 如下:
      • 1)确定边界的起始搜索点,起始点的选择很关键,对于某些图像,选择不同的起始点会导致不同的结果.
      • 2)确定合适边界判别准则和搜索准则,判别准则主要用于判断一个点是不是边界点,搜索准则则知道如何搜索下一个边缘点。
      • 3)确定搜索的终止条件。

    三、 算法原理

    边界跟踪示意图,图中黑点表示边界点,白点为图像的内部点
    • 跟踪的初始点是最左下方的黑点(即最后一行的最左黑点),跟踪的初始方向设定为左上角45度。
    • 跟踪开始后,初始点沿初始跟踪方向检测该方向是否有黑点(检测距离为一个像素点),如果是,则保存初始点,将检测到的点作为新的初始点,同时在原来检测的基础上,逆时针旋转90度作为新的跟踪方向。如果不是目标点,则沿顺时针旋转45度,沿新跟踪方向继续检测,直到找到黑色像素,然后将跟踪方向逆时针旋转90作为新的跟踪方向。
    • 重复上面不断改变跟踪方向,直到找到新的边界点。找到新的边界点后,将旧的边界点保存,将新检测到的点作为新的初始点。
    • 这样不断重复上述过程,直到检测点回到最开始的检测点为止。

    注意:中心像素可以跟踪的方向有8个,对每个方向制定了方向编号以及偏移量,如下图所示。一般来说,通常选取图像的最左下角的像素点作为起点。


    四、程序

    import cv2
    import numpy as np
     
    
    # 图像二值化
    def get_binary_img(img):
        # gray img to bin image
        bin_img = np.zeros(img.shape,np.uint8)
        h = img.shape[0]
        w = img.shape[1]
        for i in range(h):
            for j in range(w):
                bin_img[i][j] = 255 if img[i][j] > 200 else 0
        return bin_img
    
    # 边界跟踪, 从左上角查找开始
    def get_left_up_start_pt(bin_img):
        h = bin_img.shape[0]
        w = bin_img.shape[1]
        find = 0
        start_i = 0
        start_j = 0
        for i in range(h):
            for j in range(w):
                if bin_img[i][j] == 0:
                    find = 1
                    start_i = i
                    start_j = j
                    break
        return find,start_i,start_j
    
    def trace_contour(bin_img,find,start_i,start_j):
        contour_img = np.zeros(shape=(bin_img.shape), dtype=np.uint8)
        contour_img += 255
        if find:
            contour_img[start_i][start_j] = 0
    
        Direct = [(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1),(-1,0)]
        BeginDirect = 0
        findstart = 0
        cur_i = start_i
        cur_j = start_j
    
        while findstart==0 :
            findpoint = 0
            while findpoint==0:
                i = cur_i + Direct[BeginDirect][1]
                j = cur_j + Direct[BeginDirect][0]
                pixel = bin_img[i][j]
                if pixel==0:
                    findpoint = 1
                    cur_i = i
                    cur_j = j
                    if cur_i ==start_i and cur_j == start_j:
                        findstart = 1
    
                    contour_img[cur_i][cur_j] = 0
    
                    BeginDirect-=1
                    if BeginDirect == -1:
                        BeginDirect = 7
                    BeginDirect-=1
                    if BeginDirect == -1:
                        BeginDirect = 7
                else:
                    BeginDirect += 1
                    if BeginDirect == 8:
                        BeginDirect = 0
    
        return contour_img
    
    
    img = cv2.imread("d:\\Cup.jpg")
    gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    bin_img = get_binary_img(gray_img) 
    find, start_i, start_j = get_left_up_start_pt(bin_img)
    contour_img = trace_contour(bin_img,find,start_i,start_j)
    
    cv2.imshow("img",img)
    cv2.imshow("gray_img",gray_img)
    cv2.imshow("bin_img",bin_img)
    cv2.imshow("contour_img",contour_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    五、资料

    赵卓不凡的博客:《目标轮廓提取之边界跟踪法》
    https://blog.csdn.net/sgzqc/article/details/119631617
    

    相关文章

      网友评论

        本文标题:目标轮廓提取之边界跟踪法

        本文链接:https://www.haomeiwen.com/subject/rtdgmdtx.html