如何优化凸包绘图?

How to optimize convex hull drawing?

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

  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('')

封面图片:

输入图像:

最终图片:

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

那将是我的最终输出:

  1. 找到第一张图片中的所有“blob”轮廓。
  2. 迭代“blob”轮廓,并在单独的黑色背景上绘制每个轮廓,cf。 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
----------------------------------------