如何优化凸包绘图?

问题描述

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

  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),line_thickness)
    except:
        print('')

封面图片

Cover Image

输入图像:

Input Image

最终图像:

final image

解决方法

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

那将是我的最终输出:

Output

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