【问题标题】:How to properly use cv2.findContours() on opencv version 4.4.0.?如何在 opencv 4.4.0 版上正确使用 cv2.findContours()?
【发布时间】:2020-10-14 02:03:46
【问题描述】:

我正在尝试在 opencv 4.4.0 版上使用 cv2.findContours()。 (我使用 Python 3.8.5 版)但它会引发错误,我无法弄清楚。我不确定代码有什么问题。这里有一些背景:

  • 根据 OpenCV,cv2.findContours() 的语法如下: Python: 轮廓,层次结构= cv.findContours(图像,模式,方法[,轮廓[,层次结构[,偏移量]]])

  • 我查找了一些示例以确保如何正确实现它,以下是我的发现: 示例 1 _,轮廓,_ = cv2.findContours(binary_image,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

示例 2 (_, cnts, _) = cv2.findContours(thresholded.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

这些来自我在网上找到的工作项目,有很多这样的例子。所以,我试图实现我从视频中获得的一些代码,以获得对该主题的一些理解,但它似乎对我不起作用,我找不到原因。代码如下:

import cv2 
import numpy as np 

imagen =cv2.imread('lettuce.jpg')
gray = cv2.cvtColor(imagen,cv2.COLOR_BGR2GRAY)
_,binary = cv2.threshold(gray,100,255,cv2.THRESH_BINARY)

image,contours,hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(image,contours, -1, (0,255,0),3)

错误: 回溯(最近一次通话最后): 第 8 行,在 图像,轮廓,层次结构 = cv2.findContours(二进制,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) ValueError: 没有足够的值来解包(预期 3,得到 2)

【问题讨论】:

  • 查看答案,如果解决了,请作为答案

标签: python opencv


【解决方案1】:

在 Python/OpenCV 4.4.0 中,findContours 仅返回 2 个值,您列出 3 个。

你显示:

image,contours,hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

OpenCV 4.4.0,列表:

contours, hierarchy = cv.findContours(image, mode, method[, contours[, hierarchy[, offset]]])

请经常检查文档。见

https://docs.opencv.org/4.4.0/d3/dc0/group__imgproc__shape.html#gadf1ad6a0b82947fa1fe3c3d497f260e0

如果您想要的只是轮廓,那么以独立于版本的方式处理此问题的一种方法是(感谢@nathancy):

contours = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

如果您不想要所有嵌套轮廓,请使用 RETR_EXTERNAL 而不是 RETR_LIST。

【讨论】:

    【解决方案2】:

    问题在于 cv2.findContour 函数将返回两个而不是三个。

    1. 轮廓
    2. 层次结构

    这个 cv2.findContours 函数接受三个输入参数。第一个参数是一个应该是灰度图像的图像。第二种是检索模式,第三种是近似模式。当我们应用findContours 方法时,原始图像会受到影响。最佳做法是在处理 findContours 方法之前复制图像。

    OpenCV 将轮廓存储在列表的列表中。每个列表代表一个不同的轮廓。在列表中,该轮廓的所有坐标都添加到该列表中。 我们可以不同地存储这些坐标。我们如何存储它? approximation mode 来玩了。

    使用cv2.CHAIN_APPROX_NONE 存储所有边界点。但我们不一定需要所有的边界点。如果这些点形成一条直线,我们只需要该直线的起点和终点。改用cv2.CHAIN_APPROX_SIMPLE 仅提供边界轮廓的这些起点和终点,因此可以更有效地存储轮廓信息。

    什么是检索模式?检索模式本质上定义了轮廓的层次结构,因此层次结构就像您想要子轮廓或外部轮廓或所有轮廓一样。

    OpenCV的检索模式有四种。

    • cv2.RETR_LIST → 检索所有轮廓
    • cv2.RETR_EXTERNAL → 仅检索外部或外部轮廓
    • cv2.RETR_COMP → 检索 2 级层次结构中的所有内容
    • cv2.RETR_TREE → 检索整个层次结构中的所有内容

    层次结构按以下格式存储 [next, previous, First child, parent]。

    【讨论】:

    • 在下面查看我的答案。在 OpenCV 4.4.0 中,findContours 仅返回 2 个参数:轮廓和层次结构。
    • @fmw42,你能解决这个问题吗stackoverflow.com/questions/63933790/…
    • 我已经发布了解决方案。
    猜你喜欢
    • 2018-06-25
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 2018-02-07
    • 2018-06-21
    • 2015-12-31
    • 2017-01-12
    • 1970-01-01
    相关资源
    最近更新 更多