如何优化凸包绘图?
How to optimize convex hull drawing?
我正在尝试根据某些输入图像(下面的第二张图片)中的覆盖面积(参见下面的第一张图片)来存档绘图凸包点。对于此操作,我正在执行以下操作:
- 找到第一张图片中的轮廓。
- 找到第二张图片中的轮廓。
- 对于第一个图像中的每个轮廓区域,与第二个图像中的所有轮廓进行比较,并检查它们是否在第一个图像中的轮廓内部。如果它在等高线区域内,请将等高线的
x, y
坐标附加到列表中。
- 在列表中绘制凸包点。
我的问题是第 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 毫秒。如果这是值得的,请继续阅读。 ;-)
那将是我的最终输出:
- 找到第一张图片中的所有“blob”轮廓。
- 迭代“blob”轮廓,并在单独的黑色背景上绘制每个轮廓,cf。
cv2.drawContours
.
- 此图片与第二张图片的“细节”按位相交(相交)。
- 找到该交叉点内的所有“细节”等高线。
- 简单地连接来自“细节”轮廓的所有坐标,并调用
cv2.convexHull
。
- 在一些输出图像上绘制凸包。
这就是完整代码:
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
----------------------------------------
我正在尝试根据某些输入图像(下面的第二张图片)中的覆盖面积(参见下面的第一张图片)来存档绘图凸包点。对于此操作,我正在执行以下操作:
- 找到第一张图片中的轮廓。
- 找到第二张图片中的轮廓。
- 对于第一个图像中的每个轮廓区域,与第二个图像中的所有轮廓进行比较,并检查它们是否在第一个图像中的轮廓内部。如果它在等高线区域内,请将等高线的
x, y
坐标附加到列表中。 - 在列表中绘制凸包点。
我的问题是第 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 毫秒。如果这是值得的,请继续阅读。 ;-)
那将是我的最终输出:
- 找到第一张图片中的所有“blob”轮廓。
- 迭代“blob”轮廓,并在单独的黑色背景上绘制每个轮廓,cf。
cv2.drawContours
. - 此图片与第二张图片的“细节”按位相交(相交)。
- 找到该交叉点内的所有“细节”等高线。
- 简单地连接来自“细节”轮廓的所有坐标,并调用
cv2.convexHull
。 - 在一些输出图像上绘制凸包。
这就是完整代码:
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
----------------------------------------