【问题标题】:How to extract only outer contours from an image (OpenCV)如何从图像中仅提取外部轮廓(OpenCV)
【发布时间】:2020-05-08 12:48:51
【问题描述】:

我正在尝试使用简单的OpenCV 轮廓方法从下图中提取数字,但我在轮廓上得到重叠的边界框

cv2.RETR_EXTERNAL 应该只返回层次结构中的外部轮廓,但从下面的输出中可以看出它不起作用

代码

from matplotlib import pyplot as plt
import cv2

img = cv2.imread('image.png', 0)

_, contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

imgRGB = cv2.cvtColor(img.copy(), cv2.COLOR_GRAY2RGB)

for c in contours:
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(imgRGB, (x, y), (x+w, y+h), (0,255,0), 2)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(imgRGB, cmap='gray')

要求

opencv-python==3.4.5.20
matplotlib==3.1.2

【问题讨论】:

    标签: python python-3.x image opencv image-processing


    【解决方案1】:

    您需要先进行模糊处理,然后再应用阈值,然后才能找到轮廓。您需要这样做,因为如果您直接在灰度图像上找到轮廓,则会有微小的颗粒被拾取为轮廓。这是一个简单的过程:

    • 加载图像、灰度、高斯模糊、大津阈值
    • 使用imutils.contours.sort_contours()left-to-right 参数查找轮廓和排序
    • 获取边界框,然后使用 Numpy 切片提取 ROI

    这是检测到的以绿色突出显示的边界框

    提取/保存的 ROI

    代码

    import cv2
    from imutils import contours
    
    image = cv2.imread('1.png')
    original = image.copy()
    gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (3,3), 0)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    
    cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    (cnts, _) = contours.sort_contours(cnts, method="left-to-right")
    num = 0
    for c in cnts:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 1)
        ROI = original[y:y+h, x:x+w]
        cv2.imwrite('ROI_{}.png'.format(num), ROI)
        num += 1
    
    cv2.imshow('image', image)
    cv2.waitKey()
    

    【讨论】:

      猜你喜欢
      • 2012-11-15
      • 2020-03-14
      • 2020-06-14
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 2012-05-10
      • 1970-01-01
      相关资源
      最近更新 更多