python - OpenCV 检测具有多个边界框的单个符号

标签 python image opencv image-processing contour

我正在使用 OpenCV 将边界框放在手写的数学方程输入上。目前,我的代码有时会在单个图像的不同部分周围放置多个较小的边界框,而不是在图像周围创建一个大框。我不确定为什么会这样。我当前过滤图像并找到轮廓以绘制边界框的代码如下:

    img = cv2.imread(imgpath)

    morph = img.copy()
    morph = cv2.fastNlMeansDenoising(img)

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1))
    morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)
    morph = cv2.morphologyEx(morph, cv2.MORPH_OPEN, kernel)

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 15))

    # take morphological gradient
    gradient_image = cv2.morphologyEx(morph, cv2.MORPH_GRADIENT, kernel)

    gray = cv2.cvtColor(gradient_image, cv2.COLOR_BGR2GRAY)

    img_grey = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)

    blur = cv2.medianBlur(img_grey,3)


    ret, thing = cv2.threshold(blur, 0.0, 255.0, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

    img_dilation = cv2.dilate(thing, kernel, iterations=3)


    conturs_lst = cv2.findContours(img_dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]

实际结果示例如下:

enter image description here

OG图片:

enter image description here

最佳答案

你有正确的想法,但我认为你过度使用 cv2.morphologyEx不断侵 eclipse 和扩大图像。你提到你的问题:

Currently, my code sometimes places multiple smaller bounding boxes around different parts of a singular image instead of creating one large box around the image.



当您使用 cv2.findContours ,它可以正常工作,但是由于您的轮廓实际上是 Blob 而不是一个相互连接的奇异图像,因此它会创建多个边界框。要解决此问题,您可以扩大图像以将 blob 连接在一起。

我已经重写了你的代码,没有额外的 cv2.morphologyEx重复。主要思想如下:
  • 将图像转为灰度
  • 模糊图像
  • 将背景与所需对象分开的阈值图像
  • 扩张图像以连接 blob 以形成奇异图像
  • 使用阈值最小/最大区域查找轮廓和过滤轮廓

  • 用于隔离所需部分的阈值图像。请注意,某些轮廓的连接已断开。为了解决这个问题,我们扩大图像以连接 blob。

    enter image description here

    扩大图像以形成奇异的物体。现在请注意,我们在底部有不需要的水平部分,我们可以找到轮廓,然后使用区域过滤以删除该部分。

    enter image description here

    结果

    enter image description here

    enter image description here
    import numpy as np
    import cv2
    
    original_image = cv2.imread("1.jpg")
    image = original_image.copy()
    
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (3, 3), 0)
    thresh = cv2.threshold(blurred, 160, 255, cv2.THRESH_BINARY_INV)[1]
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    dilate = cv2.dilate(thresh, kernel , iterations=4)
    
    cv2.imshow("thresh", thresh)
    cv2.imshow("dilate", dilate)
    
    # Find contours in the image
    cnts = cv2.findContours(dilate.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    
    contours = []
    
    threshold_min_area = 400
    threshold_max_area = 3000
    
    for c in cnts:
        x,y,w,h = cv2.boundingRect(c)
        area = cv2.contourArea(c)
        if area > threshold_min_area and area < threshold_max_area:
            # cv2.drawContours(original_image,[c], 0, (0,255,0), 3)
            cv2.rectangle(original_image, (x,y), (x+w, y+h), (0,255,0),1)
            contours.append(c)
    
    cv2.imshow("detected", original_image) 
    print('contours detected: {}'.format(len(contours)))
    cv2.waitKey(0)
    

    关于python - OpenCV 检测具有多个边界框的单个符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56105512/

    相关文章:

    android - .gif 图像作为源在 Windows kivy 程序中运行良好。通过 kivy Launcher 运行显示 gif 图像的背景

    python - 消除opencv中阈值TEXT图像的噪音

    matlab - 如何实现 3d 重建算法

    python - tensorflow 范围名称的限制是什么?

    python - 很难在 pygame 代码中找到涉及奇怪物理行为的错误

    ios - 在编辑模式下将图像添加到 UITableViewCell 未正确对齐

    image - 检测模糊图像中的细线

    opencv - 如何在不使用 OpenCV 中内置函数翻转的情况下进行翻转?

    python - 从 PIL 导入图像 - ImportError : No module named PIL

    python - 在有向树的广度优先搜索中跟踪深度