2301_77755930 2024-05-10 11:47 采纳率: 78.6%
浏览 11
已结题

Python,轮廓中轴线,中轴线垂线

img


利用Python将二值图中目标轮廓进行处理将轮廓细化成骨架线,并将骨架线作为目标轮廓中轴线,绘制在目标轮廓内,如图;

img

然后在中轴线垂直方向再绘制中轴线垂线,画一定数量条中轴线垂线。如图;

img

  • 写回答

4条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-05-10 11:47
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    问题分析: 本题要求利用Python将二值图中目标轮廓进行处理,将轮廓细化成骨架线,并将骨架线作为目标轮廓中轴线,绘制在目标轮廓内。接着在中轴线垂直方向再绘制一定数量条中轴线垂线。 解决方案:
    • 利用OpenCV库中的findContours函数获取轮廓。
    • 利用OpenCV库中的morphologyEx函数将轮廓细化成骨架线,具体方法为开运算、膨胀、减去原图,然后将结果二值化即可得到骨架线。
    • 利用OpenCV库中的drawContours函数将目标轮廓及其中轴线绘制出来。
    • 计算中轴线的控制点,然后绘制垂线。 代码实现如下:
    import cv2
    import numpy as np
    # 读取图片
    img = cv2.imread('image_path', 0)
    # 获取轮廓
    _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    cnt = contours[0]
    # 获取骨架线
    kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
    skel = np.zeros(thresh.shape, np.uint8)
    while cv2.countNonZero(thresh) > 0:
        eroded = cv2.erode(thresh, kernel)
        temp = cv2.dilate(eroded, kernel)
        temp = cv2.subtract(thresh, temp)
        skel = cv2.bitwise_or(skel, temp)
        thresh = eroded.copy()
    # 获取控制点
    def get_control_points(contour):
        M = cv2.moments(contour)
        cX, cY = int(M['m10'] / M['m00']), int(M['m01'] / M['m00'])
        distances = []
        for point in contour:
            x, y = point[0]
            distance = np.sqrt((x - cX) ** 2 + (y - cY) ** 2)
            distances.append(distance)
        median_distance = np.median(distances)
        control_points = []
        for point in contour:
            x, y = point[0]
            distance = np.sqrt((x - cX) ** 2 + (y - cY) ** 2)
            if distance < median_distance:
                control_points.append((x, y))
        return control_points
    # 获取中轴线
    control_points = get_control_points(cnt)
    mid_points = [(control_points[i] + control_points[i+1]) // 2 for i in range(len(control_points) - 1)]
    mid_points.append((control_points[-1] + control_points[0]) // 2)
    # 绘制目标轮廓及其中轴线
    img_contour = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    cv2.drawContours(img_contour, [cnt], -1, (0, 0, 255), 2)
    cv2.polylines(img_contour, [np.array(control_points)], False, (255, 0, 0), 2)
    cv2.imshow('contour with skeleton', img_contour)
    # 绘制中轴线垂线
    img_mid_points = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    for point in mid_points:
        x, y = point
        cv2.line(img_mid_points, (x, y), (x, y + 50), (0, 255, 0), 2)
    cv2.imshow('mid points', img_mid_points)
    cv2.waitKey(0)
    

    参考资料: 1. OpenCV中的轮廓:https://docs.opencv.org/master/dd/d49/tutorial_py_contour_features.html 2. OpenCV中的形态学:https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=morphologyex#cv2.morphologyEx 3. OpenCV中的绘图函数:https://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html 4. 中轴线的计算方法:https://blog.csdn.net/weixin_43218314/article/details/86717744

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 5月18日
  • 已采纳回答 5月10日
  • 创建了问题 5月10日

悬赏问题

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