【问题标题】:How to optimize convex hull drawing?如何优化凸包绘制?
【发布时间】:2021-05-13 22:19:20
【问题描述】:

我正在尝试根据某些输入图像(下面的第二个图像)中的覆盖区域(参见下面的第一个图像)来存档绘制凸包点。对于此操作,我正在执行以下操作:

  1. 在第一张图片中找到轮廓。
  2. 在第二张图片中找到轮廓。
  3. 对于第一张图像中的每个轮廓区域,与第二张图像中的所有轮廓进行比较,并检查它们是否在第一张图像的轮廓内。如果在轮廓区域内,则将轮廓的x, y 坐标附加到列表中。
  4. 在列表中绘制凸包点。

我的问题是第 3 步花费了太多时间,因为比较了第二张图像中的每个轮廓。有没有办法优化这段代码?

for coverContour in coverContours:
    try:
        points_ = []
        for pointsContour in pointsContours:

            ((x, y), r) = cv2.minEnclosingCircle(pointsContour)

            if (cv2.pointPolygonTest(coverContour, (int(x), int(y)), False)) == 1:
                point_list.append((int(x), int(y)))
                points_.append(Point(int(x), int(y)))

        draw_point = Point.convex_hull(points_, len(points_))
        for x in range(len(draw_point)-1):
            cv2.line(layer, (points_[draw_point[x]].x, points_[draw_point[x]].y),
                     (points_[draw_point[x+1]].x, points_[draw_point[x+1]].y), (255, 255, 255), line_thickness)

        cv2.line(layer, (points_[draw_point[len(draw_point)-1]].x, points_[draw_point[len(draw_point)-1]].y),
                 (points_[draw_point[0]].x, points_[draw_point[0]].y), (255, 255, 255), line_thickness)
    except:
        print('')

封面图片:

输入图片:

最终图像:

【问题讨论】:

    标签: python opencv optimization convex-hull


    【解决方案1】:

    我没有测试你的代码,因为它缺少开箱即用的部分,所以我不知道如何量化在这里花费太多时间。下面提到的方法在我的机器上大约需要 50 毫秒(i7 3.60 GHz,32 GB RAM)。如果值得,请继续阅读。 ;-)

    这将是我的最终输出:

    1. 从第一张图片中找出所有“斑点”轮廓。
    2. 迭代“斑点”轮廓,并在单独的黑色背景上绘制每个轮廓,参见。 cv2.drawContours
    3. 按位并(相交)此图像与第二张图像中的“细节”。
    4. 找到该交点内的所有“细节”轮廓。
    5. 只需连接“细节”轮廓中的所有坐标,然后调用cv2.convexHull
    6. 在某些输出图像上绘制凸包。

    这就是完整的代码:

    import cv2
    import numpy as np
    
    # Read input images
    blobs = cv2.imread('6Sh0t.png', cv2.IMREAD_GRAYSCALE)
    details = cv2.imread('RdKkN.png', cv2.IMREAD_GRAYSCALE)
    
    # Find blob contours w.r.t. the OpenCV version
    cnt_blobs = cv2.findContours(blobs, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    cnt_blobs = cnt_blobs[0] if len(cnt_blobs) == 2 else cnt_blobs[1]
    
    # Prepare output image
    output = np.zeros_like(blobs)
    
    # Iterate all blob contours
    for cnt in cnt_blobs:
    
        # Draw blob contour on empty, black background
        tmp = np.zeros_like(blobs)
        tmp = cv2.drawContours(tmp, [cnt], -1, 255, cv2.FILLED)
    
        # Bitwise and (intersection) blob contour with details
        tmp = cv2.bitwise_and(tmp, details)
    
        # Find details contours within intersection w.r.t. the OpenCV version
        cnts = cv2.findContours(tmp, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    
        # Concatenate all coordinates, and get convex hull
        cnts = np.concatenate(cnts, axis=0)
        cnts = cv2.convexHull(cnts)
    
        # Draw in output
        output = cv2.drawContours(output, [cnts], -1, 128, 3)
    
    # Output
    cv2.imshow('Output', output)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    ----------------------------------------
    System information
    ----------------------------------------
    Platform:      Windows-10-10.0.16299-SP0
    Python:        3.8.5
    NumPy:         1.19.5
    OpenCV:        4.5.1
    ----------------------------------------
    

    【讨论】:

    • 让我再问你一个问题。有没有什么简单的方法可以在同一斑点区域中的每个点(轮廓)上画一条线? (我正在尝试将每个点连接到同一 blob 区域中的其他点)
    • 很遗憾,我不明白您的后续问题。也许,ask another question 在那里详细描述了您的问题,也许可以参考这里以获得更多上下文。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 2018-06-20
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    相关资源
    最近更新 更多