项目场景:
在使用python+opencv进行图片处理的过程中,需要对图片中的形状轮廓进行读取,于是就使用findContours函数进行查找轮廓。
问题描述
对问题进行分析,它的意思是“值错误:太多的值需要解包(预期为2)”
意思应该是:cv2.findContours() 函数返回两个值(预期是两个),但是我没有解包这两个值的地方。
我程序中的写法如下:
# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
不是已经有两个获取变量了吗?为什么会这样
解决方案:
我这里先给出解决方法吧,给出三个获取位置就可以了
代码改成下述这样即可:
# 查找轮廓
_, contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
问题分析及总结:
由于我刚刚接触python编程,对于这种接收几个返回值的情况是第一次接触
首先进行搜索cv2.findContours函数
contours, hierarchy = cv2.findContours(image, mode, method, contours=None, offset=None)
image: 输入的二值化图像
mode: 轮廓检索模式,表示轮廓的检索模式。常用的有 cv2.RETR_EXTERNAL、cv2.RETR_LIST 等
method: 轮廓逼近方法,表示轮廓的逼近方法。常用的有 cv2.CHAIN_APPROX_SIMPLE、cv2.CHAIN_APPROX_NONE 等
contours: 输出参数,包含检测到的轮廓的列表。每个轮廓是一个表示点集的numpy数组。
hierarchy: 输出参数,包含轮廓的层次结构信息,是一个numpy数组。
通过查找资料,可能是在较新的版本中,cv2.findContours() 函数只返回轮廓列表,而不返回层次结构。所以只有一个返回值,所以应该接收返回值应该是要修改成
_, contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
但是令我很不理解的是,这样写难道不是有三个返回值然后忽略了第一个和第三个吗?事实上确实是只接受了轮廓列表(contours),但是我要是直接使用
contours = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
后续使用contours轮廓的时候就会找不到有效轮廓。
后续经过查找,终于发现!!!!
在OpenCV中,cv2.findContours 返回的第一个值是轮廓的列表,但在Python中,它的返回值实际上是一个包含两个元素的元组 (contours, hierarchy)。所以,当您使用
contours = cv2.findContours(…) 时,contours 变量实际上是一个元组,而不是轮廓的列表。
因此,使用 _, contours, _ 的形式是一种常见的做法,它只关心轮廓的列表而忽略了元组中的其他值。这使得代码更简洁,而不必额外使用索引来获取轮廓列表。要不然就要使用contours[0]来进行索引了。
所以在使用的时候,直接使用_, contours, _进行接收返回值就可以了。
记录BUG问题,欢迎指正讨论!