【问题标题】:filling contours with opencv python用opencv python填充轮廓
【发布时间】:2013-10-13 21:05:57
【问题描述】:

我有带有折线的二进制图像:

cv2.polylines(binaryImage,contours,1, (255,255,255))

我现在需要的是填充所有折线的有效方法。我在opencv中没有找到这种方法,但也许它存在。或者,也许我可以实现算法来完成这项工作(但速度很快——我有高清图片)。请分享您的想法..

【问题讨论】:

    标签: c++ python image opencv


    【解决方案1】:

    我认为您正在寻找的是cv2.fillPoly,它填充了由一个或多个多边形包围的区域。这是一个简单的 sn-p,我生成代表正方形顶点的四个点的轮廓,然后用白色填充多边形。

    import numpy as np
    import cv2
    
    contours = np.array( [ [50,50], [50,150], [150, 150], [150,50] ] )
    img = np.zeros( (200,200) ) # create a single channel 200x200 pixel black image 
    cv2.fillPoly(img, pts =[contours], color=(255,255,255))
    cv2.imshow(" ", img)
    cv2.waitKey()
    

    【讨论】:

      【解决方案2】:

      cv2.drawContours()thickness=cv2.FILLED 一起使用:

      cv2.drawContours(img, contours, -1, color=(255, 255, 255), thickness=cv2.FILLED)
      

      【讨论】:

      • 这是填充轮廓和边框还是将边框留在外面?
      • @Abr 为我工作
      • 或者直接输入thickness=-1
      • 或者只是输入thickness=cv2.FILLED,因为这样更清楚。 :)
      【解决方案3】:

      如果您的轮廓是闭合的,您可以使用fillPolydrawContours。将@jabaldonedo 和@ash-ketchum 结合在一起回答:

      import cv2
      import matplotlib.pyplot as plt
      import numpy as np
      
      # Lets first create a contour to use in example
      cir = np.zeros((255,255))
      cv2.circle(cir,(128,128),10,1)
      res = cv2.findContours(cir.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
      contours = res[-2] # for cv2 v3 and v4+ compatibility
      
      # An open circle; the points are in contours[0]
      plt.figure()
      plt.imshow(cir)
      
      # Option 1: Using fillPoly
      img_pl = np.zeros((255,255))
      cv2.fillPoly(img_pl,pts=contours,color=(255,255,255))
      plt.figure()
      plt.imshow(img_pl)
      
      # Option 2: Using drawContours
      img_c = np.zeros((255,255))
      cv2.drawContours(img_c, contours, contourIdx=-1, color=(255,255,255),thickness=-1)
      plt.figure()
      plt.imshow(img_c)
      
      plt.show()
      

      img_pl 和 img_c 都包含一个从轮廓 [0] 中的点开始的实心圆

      对于上下文,这是使用 python 3.6.2、OpenCV (cv2.version) 3.2.0、numpy 1.13.1 和 matplotlib 2.0.2 测试的。我怀疑它适用于任何 cv2 3+ 和 python 3.5+。根据@elyas-karimi(和 OpenCV 文档),findContours 在 3.* 中返回 3 个值,在 4.* 中返回 2 个值,丢弃图像返回(并且自 3.2 起未修改)。

      【讨论】:

      • 运行代码会出现此错误:ValueError: not enough values to unpack (expected 3, got 2)
      • @OmarShabab 也许你的 OpenCV 版本不同。在更高版本中,cv2.findContours() 只返回两个参数,而不是三个。您只需要像这样使用此方法:contours, _ = cv2.findContours(cir.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)(刚刚删除了第一个“_”符号)。这是 OpenCV 文档(OpenCV 4.3.0):docs.opencv.org/4.3.0/d4/d73/tutorial_py_contours_begin.html
      【解决方案4】:

      我知道 OP 询问了有关使用 OpenCV 的具体问题,但我最终只是试图填充我拥有的分割多边形(此外,OpenCV 对我的情况来说有点问题)库,我相信许多其他用户也这样做了也是,所以这是我使用scikit imagepolygonfunction的解决方案。

      来自文档:

      import matplotlib.pyplot as plt
      
      from skimage.draw import line, polygon, circle, ellipse
      import numpy as np
      
      
      img = np.zeros((500, 500, 3), 'uint8')
      
      # draw line
      rr, cc = line(120, 123, 20, 400)
      img[rr,cc,0] = 255
      
      # fill polygon
      poly = np.array((
          (300, 300),
          (480, 320),
          (380, 430),
          (220, 590),
          (300, 300),
      ))
      rr, cc = polygon(poly[:,0], poly[:,1], img.shape)
      img[rr,cc,1] = 255
      
      # fill circle
      rr, cc = circle(200, 200, 100, img.shape)
      img[rr,cc,:] = (255, 255, 0)
      
      # fill ellipse
      rr, cc = ellipse(300, 300, 100, 200, img.shape)
      img[rr,cc,2] = 255
      
      plt.imshow(img)
      plt.show()
      

      结果:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-26
        • 2016-10-21
        • 1970-01-01
        • 1970-01-01
        • 2014-04-05
        • 1970-01-01
        • 2013-04-23
        相关资源
        最近更新 更多