我使用OpenCV编写了一个小应用程序,用于计算特定细节的参数。
重点是因为细节闪烁,我无法获得它的精确轮廓。就像this。如您所见,细节中心为白色,因此结果轮廓看起来像马蹄形。
我也不能使用凸包来包裹获得的轮廓,因为我会失去精度,这取决于我的情况。
在我看来,我已经有了解决此问题的方法。这个想法是:
获取细节轮廓的凸包
从船体区域中减去轮廓区域,并获取船体而不是细节轮廓所包含的多边形列表
选择此类多边形中的最大多边形并将其添加到轮廓中
我仍然不知道的一件事是,是否有任何方法可以用OpenCV以我需要的形式来区分各个区域?
任何帮助表示赞赏
答案 0 :(得分:0)
好吧,最后我实现了自己的解决方案。它可以很好地满足我的需要,但是从一种形状减去另一种形状的方法仅适合于从其凸包中减去轮廓。
import numpy
import cv2
import matplotlib.pyplot as plt
from config.config import Config
from shapely.geometry import Polygon
from shapely.ops import cascaded_union
cfg = Config.get_config(None)
def __cure_detail_contour(self, contour):
# processes the contour and its convex hull and gives back contour without light notch
contour_hull = cv2.convexHull(contour)
# find product of subtraction contour from its convex hull
subtraction_polygons = []
previous_polygon = []
for contour_point in contour:
previous_polygon.append([[contour_point[0][0], contour_point[0][1]]])
if cv2.pointPolygonTest(contour_hull, (contour_point[0][0], contour_point[0][1]), False) == 0:
if len(previous_polygon) > 2:
subtraction_polygons.append(previous_polygon)
previous_polygon = [[[contour_point[0][0], contour_point[0][1]]]]
# in the list of subtracted polygons find one with maximum area. Consider this one to be the notch
max_flaw_area = 0
max_area_polygon = None
for sub_contour in subtraction_polygons:
cv_contour = numpy.array(sub_contour)
area = cv2.contourArea(cv_contour)
if area > max_flaw_area:
max_flaw_area = area
max_area_polygon = sub_contour
# checking ratio of contour area to the maximal flaw error to avoid
# smoothing edge flaws (to avoid losing preciseness)
contour_area = cv2.contourArea(contour)
if max_flaw_area < cfg.cure_flaw_min_area_coeff * contour_area:
return contour
polygon = Polygon([[p[0][0], p[0][1]] for p in max_area_polygon])
contour_polygon = Polygon([[p[0][0], p[0][1]] for p in contour])
result_contour = cascaded_union([polygon, contour_polygon])
# x, y = polygon.exterior.xy
# plt.plot(x, y, "bo")
# plt.show()
#
# x, y = contour_polygon.exterior.xy
# plt.plot(x, y, "g")
# plt.show()
x, y = result_contour.exterior.xy
# plt.plot(x, y, "r")
# plt.show()
contour = numpy.array([ [[numpy.int32(x[i]), numpy.int32(y[i])]] for i in range(min(len(x), len(y)))])
return contour