【问题标题】:Get list of differences between contour and its convex hull获取轮廓与其凸包之间的差异列表
【发布时间】:2019-02-14 17:11:13
【问题描述】:

我用OpenCV写了一个小应用,用来统计具体细节的参数。

关键是因为细节闪烁我无法得到它的精确轮廓。就像this。如您所见,细节中心是白色的,因此结果轮廓看起来像马蹄铁。

我也不能使用凸包来包裹获得的轮廓,因为我会失去在我的情况下很重要的准确性。

在我看来,我已经有了这个问题的解决方案。这个想法是:

  1. 获取细节轮廓的凸包

  2. 从船体面积中减去轮廓面积,得到船体包含的多边形列表,而不是细节的轮廓

  3. 选择最大的多边形并将其添加到轮廓中

我仍然无法弄清楚的一件事是,是否有任何方法可以通过 OpenCV 以我需要的形式获得区域之间的差异?

任何帮助表示赞赏

【问题讨论】:

  • 这是一个凸对象。为什么你会失去凸包的准确性?
  • 好吧,也许这个例子不是最好的。细节边缘不理想,实际上是折线。当我得到凸包时,它会平滑所有缺陷。然后当我计算细节的体积(作为轮廓的旋转积分)时,它很有意义。

标签: python opencv computer-vision


【解决方案1】:

好吧,最后我实现了自己的解决方案。它非常适合我的需要,但是从另一个形状中减去一个形状的方法仅适用于从其凸包中减去轮廓。

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

【讨论】:

    猜你喜欢
    • 2014-07-31
    • 2013-06-15
    • 2011-03-28
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    相关资源
    最近更新 更多