2301_77755930 2024-04-24 21:04 采纳率: 78.6%
浏览 10
已结题

Python,图像处理,骨架线,中轴线

img


利用Python对以上二值图中白色的纤维目标,在原图绘制中轴线,首先对原图进行轮廓细化处理,提取出骨架线,同时对于骨架线上的毛刺进行去除,只保留主干骨架线,然后将提取的骨架线绘制到原图白色纤维轮廓内部。

  • 写回答

1条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-04-24 21:21
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    问题分析:
    1. 如何对图片进行轮廓细化处理?
    2. 如何提取出骨架线?
    3. 如何去除骨架线上的毛刺?
    4. 如何将骨架线绘制到原图内部? 解决方案:
    5. 对于二值图像,可以使用opencv中的函数cv2.ximgproc.thinning()进行轮廓细化处理。代码示例:
    import cv2
    img = cv2.imread("image.png", 0)
    thinned_img = cv2.ximgproc.thinning(img, None, cv2.ximgproc.THINNING_ZHANGSUEN)
    
    1. 提取出骨架线,可以使用opencv中的函数cv2.connectedComponents()。可以通过遍历像素的方式,判断其是否为端点或交叉点,然后在骨架线上将其标记为白色像素。
    import numpy as np
    # 寻找端点和交叉点的函数
    def find_junctions(endpoint_img, kernel=None):
        if kernel is None:
            kernel = np.ones((3, 3), np.uint8)
        junctions = np.zeros_like(endpoint_img)
        connected = cv2.connectedComponents(endpoint_img)
        labels = connected[1]
        junction_values = []
        for i in range(1, connected[0]):
            g = (labels == i)
            num = np.sum(g)
            if num == 1:
                junctions[g] = 1
                junction_values.append((np.argmax(g) // labels.shape[1], np.argmax(g) % labels.shape[1]))
            elif num > 2:
                junctions[g] = 1
                junction_values.append((np.argmax(g) // labels.shape[1], np.argmax(g) % labels.shape[1]))
        junctions = cv2.dilate(junctions, kernel, iterations=1)
        junctions = junctions - endpoint_img
        return junctions, junction_values
    # 提取骨架线的函数
    def get_skeleton(img):
        skel = np.zeros_like(img)
        img = img.copy()
        while True:
            endpoint_img = cv2.morphologyEx(img, cv2.MORPH_HITMISS, np.array([[0, 0, 0], [0, 1, 0], [1, 1, 1]]))
            if np.sum(endpoint_img) == 0:
                break
            junctions_img, _ = find_junctions(endpoint_img)
            skel = skel + endpoint_img
            img = cv2.subtract(img, endpoint_img)
            img = cv2.subtract(img, junctions_img)
        return skel
    img = cv2.imread("image.png", 0)
    thinned_img = cv2.ximgproc.thinning(img, None, cv2.ximgproc.THINNING_ZHANGSUEN)
    skeleton = get_skeleton(thinned_img)
    
    1. 对于骨架线上的毛刺,可以通过以下代码进行处理:
    def clean_skeleton(skeleton):
        kernel1 = np.array([[-1, -1, -1], [0, 1, 0], [1, 1, 1]], dtype=np.uint8)
        kernel2 = np.array([[1, 1, 1], [0, 1, 0], [-1, -1, -1]], dtype=np.uint8)
        skeleton = cv2.morphologyEx(skeleton, cv2.MORPH_OPEN, kernel1)
        skeleton = cv2.morphologyEx(skeleton, cv2.MORPH_OPEN, kernel2)
        return skeleton
    skeleton = clean_skeleton(skeleton)
    
    1. 将骨架线绘制到原图内部,则可以使用opencv中的函数cv2.drawContours(),示例代码:
    edged = cv2.Canny(img, 50, 150)
    thresh = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 21, 1)
    cv2.drawContours(thresh, [skeleton], 0, (255, 255, 255), -1)
    cv2.imshow("Final Result", thresh)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 5月3日
  • 已采纳回答 4月25日
  • 创建了问题 4月24日

悬赏问题

  • ¥15 数据库原理及应用上机练习题
  • ¥30 征集Python提取PDF文字属性的代码
  • ¥15 如何联系真正的开发者而非公司
  • ¥15 有偿求苍穹外卖环境配置
  • ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
  • ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
  • ¥15 clousx6整点报时指令怎么写
  • ¥30 远程帮我安装软件及库文件
  • ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
  • ¥20 (求远程解决)深信服vpn-2050这台设备如何配置才能成功联网?