【问题标题】:How to remove overlapping contours and separate each character as an individual contour for character extraction?如何去除重叠轮廓并将每个字符分离为单独的轮廓以进行字符提取?
【发布时间】:2019-12-31 11:12:34
【问题描述】:

我正在尝试使用opencv 中的MSER 从Python 中的图像中提取字符。这是我到目前为止的代码:

import cv2
import numpy as np

# create MSER object
mser = cv2.MSER_create()
# convert image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# detect the regions
regions,_ = mser.detectRegions(gray)
# find convex hulls of the regions
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions]
# initialize threshold area of the contours
ThresholdContourArea = 10000
# initialize empty list for the characters and their locations
char = []
loc =[]
# get the character part of the image and it's location if the area of contour less than threshold
for contour in hulls:
    if cv2.contourArea(contour) > ThresholdContourArea:
        continue
    # get the bounding rectangle around the contour
    bound_rect = cv2.boundingRect(contour)
    loc.append(bound_rect)
    det_char = gray[bound_rect[1]:bound_rect[1]+bound_rect[3],bound_rect[0]:bound_rect[0]+bound_rect[2]]
    char.append(det_char)

但是这种方法为同一个字母提供了多个轮廓,并且在某些地方多个单词被放入一个轮廓中。这是一个例子: 原图:

添加轮廓后:

这里第一个 T 周围有多个轮廓,两个 rs 组合成一个轮廓。我该如何预防?

【问题讨论】:

  • 您为什么使用 MSER 而不是某种阈值处理?
  • 那么如何提取字母呢?我尝试了cv2.findContours() 函数,但它只返回最外层的轮廓
  • 你能发布你的原始图片吗?
  • @Ziri 添加了原图
  • findContours 为您提供所有字母。您只需要正确设置层次结构。此来源可以帮助您:docs.opencv.org/trunk/d9/d8b/…

标签: python opencv image-processing computer-vision mser


【解决方案1】:

这里不使用MSER,而是使用阈值+轮廓过滤的简单方法。我们首先去除边界然后去除 Otsu 的阈值以获得二值图像。这个想法是每个字母应该是一个单独的轮廓。我们找到轮廓并绘制每个矩形。

移除边框->二值图像->结果

注意:在某些情况下,字母是连在一起的,为了去除合并的字符,我们可以先使用imutils.resize()放大图像,然后执行erosionmorphological opening将每个字符分开.但是,我无法获得很好的结果,因为即使使用最小尺寸的内核,文本也会消失。

代码

import cv2
import imutils

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
image = imutils.resize(image, width=500)

# Remove border
kernel_vertical = cv2.getStructuringElement(cv2.MORPH_RECT, (1,50))
temp1 = 255 - cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel_vertical)
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50,1))
temp2 = 255 - cv2.morphologyEx(image, cv2.MORPH_CLOSE, horizontal_kernel)
temp3 = cv2.add(temp1, temp2)
result = cv2.add(temp3, image)

# Convert to grayscale and Otsu's threshold
gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Find contours and filter using contour area
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(result, (x, y), (x + w, y + h), (36,255,12), 2)

cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.waitKey()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-07
    • 2019-12-24
    • 1970-01-01
    • 2011-05-24
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    相关资源
    最近更新 更多