【问题标题】:Remove an opencv contour from a list of contours [duplicate]从轮廓列表中删除opencv轮廓[重复]
【发布时间】:2018-10-29 17:57:30
【问题描述】:

使用opencv,我正在检测轮廓并选择其中一些:

CNTS = []
_, contours, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
    if some_condition(c):
        CNTS.append(c)

然后我循环遍历轮廓列表的 2 个子集 {c1, c2},并删除其中一些:

TMP = CNTS[:]  # copy it, to avoid deleting element from a list while looping on it!
for c1, c2 in itertools.combinations(TMP, 2):
    if dist(c1, c2) < 100  # custom function to evaluate distance between 2 contours
        if c1 in CNTS:  # it might have been already removed
            CNTS.remove(c1)

CNTS.remove(c1) 行中的问题来了:

ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()

如何从opencv轮廓列表中正确删除轮廓?

注意:事实上,它大部分时间都有效,但有时,经过几次迭代后,我会遇到这个错误。也许是因为轮廓是一个点列表,然后测试“点列表”是否是另一个列表的成员是不明确的?

更一般地说,在 Python 中,当测试点列表(=2 个元素的列表!)本身是否是另一个列表的成员时,是否存在一些模棱两可的情况?

【问题讨论】:

  • Contour 是一个点列表(或 np.ndarray),你应该定义你的自定义 dist 函数。但你还没有表现出来。
  • @Silencer 我修复了问题中的错误复制/粘贴。问题出在.remove(c1) 行。这就像测试c1(点列表或np.ndarray)是否是CNTS列表的成员有问题。
  • 尝试通过索引迭代它们,然后保存到一个新的轮廓。
  • 您已经在制作列表的副本,所以您是否对简单过滤轮廓并创建新列表而不是使用CNTS.remove() 的答案感兴趣?我在轮廓列表上使用.remove() 进行了测试,顺便说一下,它似乎工作正常。
  • @Silencer:这就是我最终要做的:我保留一个轮廓 indexes 列表,并在 integers 列表中进行删除。这当然可行,但通常使用 Python 可以避免此类事情(我会一直在 C 中这样做!)并使用对象列表而不是索引列表。

标签: python list opencv itertools opencv-contour


【解决方案1】:

您已将其删除。出现错误是因为您尝试将其删除两次。

试试这个:

popup = []
for i in range(len(CNTS)):
    for j in range(i+1, len(CNTS)):
        if dist(CNTS[i], CNTS[j]) < 100:
            popup.append(i)
            break
for i in popup[::-1]:
    CNTS.pop(i)

【讨论】:

  • 谢谢。事实上,在我的代码中,我已经检查过它是否已经被删除(检查更新的问题)。
猜你喜欢
  • 2020-06-14
  • 2016-09-25
  • 1970-01-01
  • 2022-01-23
  • 2019-03-20
  • 1970-01-01
  • 1970-01-01
  • 2014-07-12
  • 1970-01-01
相关资源
最近更新 更多