python - 如何从图像中仅提取外部轮廓(OpenCV)

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

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

enter image description here

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

enter image description here

代码:

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

最佳答案

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

  • 加载图像、灰度、高斯模糊、Otsu 阈值
  • 使用 imutils.contours.sort_contours() 查找轮廓并排序使用从左到右参数
  • 获取边界框,然后使用 Numpy 切片提取 ROI
<小时/>

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

enter image description here

提取/保存的 ROI

enter image description here

代码

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()

关于python - 如何从图像中仅提取外部轮廓(OpenCV),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59858377/

相关文章:

python - 将秒转换为 hh :mm:ss in Python

python-3.x - 模块 'instaloader' 没有属性 'Instaloader'

python - 从多个类继承并更改一个父类所有方法的返回类型

android - 是否有必要将图像存储在内存中以在android中的 ListView 上显示

python - 在检测到 python 时运行特定代码

python - 值错误 : day is out of range for month

python - 在 Python 中以管理员身份编辑文件

python-3.x - Pillow 通过裁剪而不是保留纵横比来创建缩略图

javascript - 单击时如何在两个图像之间进行转换?

ios - 在ios中从服务器抓取图像