问题描述
我正在尝试根据某些输入图像(下面的第二个图像)中的覆盖区域(见下面的第一个图像)归档绘制凸包点。对于此操作,我正在执行以下操作:
- 在第一张图片中找到轮廓。
- 在第二张图片中找到轮廓。
- 对于第一张图像中的每个轮廓区域,与第二张图像中的所有轮廓进行比较,并检查它们是否在第一张图像的轮廓内。如果它在轮廓区域内,则将轮廓的
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),line_thickness)
except:
print('')
封面图片:
输入图像:
最终图像:
解决方法
我没有测试你的代码,因为它缺少开箱即用的部分,所以我不知道如何量化在这里花费太多时间。下面提到的方法在我的机器上大约需要 50 毫秒(i7 3.60 GHz,32 GB RAM)。如果值得,请继续阅读。 ;-)
那将是我的最终输出:
- 从第一张图片中找出所有“斑点”轮廓。
- 迭代“blob”轮廓,并在单独的黑色背景上绘制每个轮廓,参见。
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.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
----------------------------------------