查找最大的Contour- OpenCV,Python-获取错误

时间:2019-02-10 09:45:52

标签: python opencv image-processing opencv-contour

我正在尝试在图像中找到汽车周围的最大轮廓。
要找到轮廓,我已经从OpenCv官方文档中学到了以下内容:

 #convert the image to grayscale from rgb 
 1. image_gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
 2. threshold  = cv2.threshold(image_gray, 127,(0,255,0),0)
 3. image2, contours_list, hierarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APROX_SIMPLE)

问题-1:
我已经应用了cv2.GaussianBlur()并将其转换为HSV格式以创建遮罩,以便稍后使用MorphologyEx方法检测某些特定颜色。问题是,上面第2步中的代码要求将RGB格式的图像转换为灰度图像或将其本身转换为灰度格式,但是我使用的是HSV格式,没有这样的标记cv2.COLOR_HSV2GRAY。

我用相同的方法编写了以下2个版本来找到最大轮廓,它们抛出2个不同的错误:
在这种方法中,我首先创建一个阈值,该阈值需要一个灰度图,以传递给cv2.findContour方法

def find_biggest_contour(image):
   image = image.copy() 
   #1
   image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
   #2 
   threshold = cv2.threshold(image_gray,127, 255,0)
   #3
   image2, contours, heirarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) # countours is a python list
   contours_sizes= [(cv2.contourArea(cnt), cnt) for cnt in contours]
   biggest_contour = max(contours_sizes, key=lambda x: x[0])[1]
   #define a mask
   mask = np.zeros(image.shape, np.uint8)
   cv2.drawContours(mask,[biggest_contour], -1, (0,255,0), 3)# 3=thickness, -1= draw all contours, 2nd arg must be a list 
   return biggest_contour, mask

此方法抛出以下错误:
error for the 1st version of method 另一个版本如下(基本上,我从某个地方拿来的):

def find_biggest_contour(image):
   image = image.copy()
   im2,contours, hierarchy = cv2.findContours(image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

   contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]
   biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]

   mask = np.zeros(image.shape, np.uint8)
   cv2.drawContours(mask, [biggest_contour], -1, 255, -1)
   return biggest_contour, mask

此方法引发以下错误:
error for the 2nd version of method

请帮助我修复错误。我是opencv的新手。

2 个答案:

答案 0 :(得分:1)

我不确定,是什么原因导致您出现问题,但我敢打赌,这是由这个原因引起的

threshold = cv2.threshold(image_gray,127, 255,0)

此功能

cv2.threshold()

返回元组,因此您需要解压缩更多的值。像这样

_,threshold = cv2.threshold(image_gray,127, 255,0)

其中 _ 忽略元组的第一个返回值

,其中阈值是矩阵。

所以基本上我们是这样做的:

_, matrix = (127,'Matrix')
>>> print(matrix)
'Matrix'

这是你做的:

matrix = (127,'Matrix')
>>> print(matrix)
(127,'Matrix')

完整的代码:对我有用

import cv2
import numpy as np

hsv_image = cv2.imread('someimage.jpg',1) # pretend its HSV
rgbimg = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2RGB)
image_gray = cv2.cvtColor(rgbimg, cv2.COLOR_BGR2GRAY)
_,threshold = cv2.threshold(image_gray,127, 255,0)

im2,contours, hierarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]

biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]

注意事项:

很重要的一点是,由于某种原因(我从历史上听说过),OpenCV不是使用RGB,而是使用BGR颜色空间。只要使用灰度或仅在opencv内部(不使用RGB)工作,您甚至都不会知道。但是,一旦将数组转换为PIL,您就会知道...还有一点。在您的情况下还可以,因为将BGR转换为灰色或将RGB转换为灰色会得到相同的图像...

答案 1 :(得分:1)

从OpenCV 4.0开始,findContours()仅返回2个值,因此应为:

contours, hierarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)