【问题标题】:Find the biggest Contour- OpenCV, Python - Getting Errors找到最大的轮廓——OpenCV、Python——出现错误
【发布时间】:2019-07-04 00:55:54
【问题描述】:

我正在尝试在图像中找到汽车周围的最大轮廓。
为了找到轮廓,我从 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

此方法向我抛出以下错误:
另一个版本如下(基本上是我从某个地方拿的):

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

此方法抛出以下错误:

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

【问题讨论】:

    标签: python opencv image-processing opencv-contour


    【解决方案1】:

    我不知道到底是什么导致了你的问题,但我敢打赌这是由这个引起的

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

    这个函数

    cv2.threshold()
    

    返回tuple,所以你需要解压更多的val。像这样

    _,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 到 GRAY 或 RGB 到 GREY 会产生相同的图像......

    【讨论】:

    • 该信息很有价值,但没有解决错误。谢谢。
    • 恐怕最大的cnt是整个img,你需要过滤那些objs...
    【解决方案2】:

    从 OpenCV 4.0 开始,findContours() 只返回 2 个值,所以应该是:

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

    【讨论】:

      猜你喜欢
      • 2020-09-14
      • 2011-11-27
      • 1970-01-01
      • 1970-01-01
      • 2016-12-10
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多