开发者社区> 问答> 正文

使用opencv将曲线规格化成矩形

我有一个水下摄像头,可以检测PVC框架,如图1所示。我添加了随机的在线水的效果,所以它会在预期的粗糙条件下积累。 我尝试了两种方法: 最有效的结果是后者的结果。 我的问题是我在准备进一步处理的结果时遇到了麻烦。 为了便于处理,结果需要与最右边的部分一样具有等宽的线形。 我尝试了概率霍夫线变换来检测任何线,但它们都太弯曲了,无法检测。 问题来源StackOverflow 地址:/questions/59384117/normalizing-curved-lines-to-form-a-rectangle-using-opencv

展开
收起
kun坤 2019-12-26 15:40:56 492 0
1 条回答
写回答
取消 提交回答
  • 要从图像中提取直线,可以对阈值化后的横线和垂线进行过滤,在中心画出等宽的矩形,然后去除交叉点周围的小物体:

    import cv2
    import numpy as np
    from skimage.io import imread
    from skimage.morphology import remove_small_objects
    
    rgb = imread('https://i.stack.imgur.com/QPz8W.jpg')
    # convert to HSV for thresholding
    hsv = cv2.cvtColor(rgb, cv2.COLOR_RGB2HSV)
    
    # threshold hue channel for purple tubes, value channel for blue tubes
    thresh_hue = cv2.threshold(hsv[..., 0], 127, 255, cv2.THRESH_BINARY)[1]
    thresh_val = cv2.threshold(hsv[..., 2], 200, 255, cv2.THRESH_BINARY)[1]
    
    # combine purple tubes with blue tubes
    thresh = thresh_hue | thresh_val
    
    cv2.imwrite('threshold_result.png', thresh)
    
    # morphologically close the gaps between purple and blue tubes
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((5, 5), np.uint8))
    
    cv2.imwrite('closing_result.png', thresh)
    
    # morphological opening with horizontal and vertical kernels
    h_kernel = np.zeros((11, 11), dtype=np.uint8)
    h_kernel[5, :] = 1
    
    v_kernel = np.zeros((11, 11), dtype=np.uint8)
    v_kernel[:, 5] = 1
    
    h_tubes = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, h_kernel, iterations=6)
    v_tubes = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, v_kernel, iterations=7)
    
    cv2.imwrite('horizontal_tubes.png', h_tubes)
    cv2.imwrite('vertical_tubes.png', v_tubes)
    
    # find contours and draw rectangles with constant widths through centers
    h_contours = cv2.findContours(h_tubes, cv2.RETR_LIST,
                                  cv2.CHAIN_APPROX_SIMPLE)[0]
    h_lines = np.zeros(thresh.shape, np.uint8)
    
    for cnt in h_contours:
        x, y, w, h = cv2.boundingRect(cnt)
        y += int(np.floor(h / 2) - 4)
        cv2.rectangle(h_lines, (x, y), (x + w, y + 8), 255, -1)
    
    v_contours = cv2.findContours(v_tubes, cv2.RETR_LIST,
                                  cv2.CHAIN_APPROX_SIMPLE)[0]
    v_lines = np.zeros(thresh.shape, np.uint8)
    
    for cnt in v_contours:
        x, y, w, h = cv2.boundingRect(cnt)
        x += int(np.floor(w / 2) - 4)
        cv2.rectangle(v_lines, (x, y), (x + 8, y + h), 255, -1)
    
    # combine horizontal and vertical lines
    all_lines = h_lines | v_lines
    
    cv2.imwrite('all_lines.png', all_lines)
    
    # remove small objects around the intersections
    xor = np.bool8(h_lines ^ v_lines)
    removed = xor ^ remove_small_objects(xor, 350)
    
    result = all_lines & ~removed * 255
    
    cv2.imwrite('result.png', result)
    

    threshold_result.png

    closing_result.png

    horizontal_tubes.png

    vertical_tubes.png

    all_lines.png

    result.png

    2019-12-26 15:41:04
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载