Python 如何删除重叠轮廓并将每个字符分离为单个轮廓以进行字符提取?

Python 如何删除重叠轮廓并将每个字符分离为单个轮廓以进行字符提取?,python,opencv,image-processing,computer-vision,mser,Python,Opencv,Image Processing,Computer Vision,Mser,我试图使用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.detectRegion

我试图使用
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的周围有多个轮廓,两个R组合成一个轮廓。如何防止这种情况发生?

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

已删除边框
->
二进制图像
->
结果

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

代码


为什么要使用MSER而不是某种阈值?那么如何提取字母呢?我尝试了
cv2.findContours()
函数,但它只返回最外层的轮廓。你可以发布原始图像吗?@Ziri补充道,原始图像findContours会提供所有字母。您只需要正确设置层次结构。此来源可帮助您:
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()