• 去轮廓分支


    在一个应用中,需要提取轮廓线,但初次提取的会有一些细小分支,由于知道起点和终点,所以这里采用回溯法去掉轮廓分支

    
    import cv2
    
    
    def findPath(start, end, image, stack):
        # image: 二值图 value: 0 or 255
        # start: 起点位置 (int h, int w)
        # end:   终点位置 (int h, int w)
        h, w = image.shape[:2]
    
        if start[0] >= h or start[0] < 0 or start[1] >= w or start[1] < 0:
            return False
        if end[0] >= h or end[0] < 0 or end[1] >= w or end[1] < 0:
            return False
        stack.append(start)
        if len(image.shape) > 2:
            gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)              # 灰度化
            _, image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY)  # 二值化
    
        if image[start[0]][start[1]] != 255 or image[end[0]][end[1]] != 255:
            print("起点或者终点不符合要求")
            return False
    
        while len(stack) > 0:
            cur = stack[-1]
            x_id = cur[0]
            y_id = cur[1]
            # 八领域 右-->右下-->下-->左下-->左-->左上-->上-->右上
            nb_ids = [[x_id, y_id+1], [x_id+1, y_id+1], [x_id+1, y_id], [x_id+1, y_id-1],
                      [x_id, y_id-1], [x_id-1, y_id-1], [x_id-1, y_id], [x_id-1, y_id+1]]
            flag = -1
            for nb_id in nb_ids:
                x = nb_id[0]
                y = nb_id[1]
                if x == end[0] and y == end[1]:
                    stack.append(end_point)
                    for x in range(h):
                        for y in range(w):
                            if image[x][y] == 255:
                                image[x][y] = 0
                    return True
    
                if x >= h or x < 0 or y >= w or y < 0:
                    continue
    
                if image[x][y] == 255:
                    stack.append(nb_id)
                    image[x][y] = 128
                    flag = 1
                    break
    
            if flag == -1:
                stack.pop()
                image[x_id][y_id] = 0
    
        if len(stack) == 0:
            print("未找到")
            return False
    
    
    
    
    img_path = r"D://imageGumlineTest.png"
    img = cv2.imread(img_path)
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY)
    
    contours, hierarchy = cv2.findContours(thresh, 2, 1)
    cnt = contours[0]
    hull = cv2.convexHull(cnt, returnPoints=False)
    
    defects = cv2.convexityDefects(cnt, hull)
    max_dist = 0
    start_point = -1
    end_point = -1
    far_point = -1
    for i in range(defects.shape[0]):
        s, e, f, d = defects[i, 0]
        start = tuple(cnt[s][0])
        end = tuple(cnt[e][0])
        far = tuple(cnt[f][0])
        if d > max_dist:
            max_dist = d
            start_point = start
            end_point = end
            far_point = far
    
    cv2.line(img, start_point, end_point, [0, 255, 0], 1)
    cv2.circle(img, far_point, 2, [0, 0, 255], -1)
    print(f"start_point: {start_point}, end_point: {end_point}")
    cv2.imshow('final_img', img)
    
    skeleton_img = cv2.imread(r"D://refCenterLineTest1.png")
    gray_img = cv2.cvtColor(skeleton_img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY)
    print(f"start: {thresh[42][27]}, end: {thresh[35][289]}")
    cv2.line(skeleton_img, start_point, end_point, [0, 255, 0], 1)
    cv2.circle(skeleton_img, start_point, 3, [0, 0, 255], -1)
    cv2.circle(skeleton_img, end_point, 3, [0, 0, 255], -1)
    cv2.circle(skeleton_img, far_point, 3, [0, 0, 255], -1)
    cv2.imshow('thresh', thresh)
    
    stack = []
    s_p = [42, 27]
    e_p = [35, 289]
    findPath(s_p, e_p, thresh, stack)
    cv2.imshow("skeleton", thresh)
    
    cv2.waitKey(0)
    
    

    stack里面存放得结果即为一条起点到终点得路径

  • 相关阅读:
    Container With Most Water 容器最大水容量
    socket阻塞IO流程图
    python模块time,random,os
    python生成器表达式yield,面向过程编程,部分内置函数
    python装饰器作业
    Python函数闭包装饰器
    Python函数参数,名称空间与作用域
    Linux基础3
    Linux基础2
    linux基础1
  • 原文地址:https://www.cnblogs.com/xiaxuexiaoab/p/14792381.html
Copyright © 2020-2023  润新知