如何使用python opencv提取内部轮廓(孔)?

时间:2016-05-11 10:37:43

标签: python opencv

有一种简单直接的方法可以使用opencv 3.1 python从图像中提取内部轮廓(孔)吗?

我知道我可以使用" area"作为一个条件。但是,如果我改变图像分辨率,那么"区域"不一样。

例如,使用此图片: enter image description here 如何提取内部孔?

_, contours, hier_ = cv2.findContours(img,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
areas = [cv2.contourArea(c) for c in millCnts]
max_area = np.max(areas)
Mask = np.ones(img.shape[:2], dtype="uint8") * 255

   # I can do something like this (currently not working, just to show an example)
for c in contours:
    if(( cv2.contourArea(c) > 8) and (cv2.contourArea(c)< 100000)):
        cv2.drawContours(Mask ,[c],-1,0,1)

1 个答案:

答案 0 :(得分:5)

正如我在评论中解释的那样,您必须检查层次结构返回变量。找到轮廓后,您将获得轮廓(点列表列表)和层次结构(列表列表)。

documentation非常明确:

  

hierarchy - 可选的输出向量,包含有关的信息   图像拓扑。它具有与轮廓数量一样多的元素。对于   每个第i个轮廓轮廓[i],元素hierarchy[i][0],   hiearchy[i][1]hiearchy[i][2]hiearchy[i][3]设置为。{   基于0的指数在下一轮和前一轮的轮廓中   相同的层次级别,第一个子轮廓和父级   轮廓,分别。如果轮廓i没有下一个,   previous,parent或嵌套轮廓,相应的元素   等级[i]将是否定的。

因此,这意味着对于每个countour[i],您应该得到一个hierarchy[i],其中包含一个包含4个变量的List:

  • hierarchy[i][0]:同一级别下一个轮廓的索引
  • hierarchy[i][1]:同一级别的上一个轮廓的索引
  • hierarchy[i][2]:第一个孩子的索引
  • hierarchy[i][3]:父
  • 的索引

所以说,在你的情况下,应该有一个没有父母的,你可以通过查看hierarchy[i][3]是否为负数来检查哪一个。

应该是(未经测试的代码):

holes = [contours[i] for i in range(len(contours)) if hierarchy[i][3] >= 0]

*更新:*

总结我们在聊天中讨论的内容,

  • 图像太大,轮廓有小孔:用膨胀解决并用75号内核侵蚀
  • 由于OpenCV预期扩张为黑色背景,因此需要反转图像
  • 该算法给出了2个大轮廓,一个在外面(如预期)和一个在内部(几乎与外部轮廓相同),这可能是由于图像有一些外部(和闭合)凸起。这是通过删除没有父母及其第一个孩子的轮廓来解决的。