python - 从圆形边框内提取文本

标签 python opencv computer-vision ocr tesseract

我正在尝试使用 Python 和 OpenCV 开发一个脚本,以使用 Tesseract 的 OCR 功能检测扫描仪表图上的一些突出显示区域并输出文本。我的工作流程是首先检测感兴趣区域的大致邻近区域,然后应用处理步骤去除文本 block (线条、边框、噪声)之外的所有内容。然后将处理后的图像输入 Tesseract 的 OCR 引擎。

此工作流程适用于大约一半的图像,但由于文本触及边框而无法处理其余图像。我将在下面展示我的意思的一些示例:

第 1 步:通过使用具有荧光笔颜色范围的 InRange 创建蒙版来查找感兴趣的区域。

第 2 步:绘制感兴趣区域的轮廓,裁剪并保存到文件。

--- 引用代码从这里开始---

第 3 步:阈值图像并应用 Canny 边缘检测

第 4 步:绘制边缘轮廓并使用 cv2.approxPolyDP 将它们过滤成圆形,并查看顶点大于 8 的边缘。取第一或第二大轮廓通常对应于内边缘。

第 5 步:使用蒙版和按位运算,将轮廓内的所有内容都转移到白色背景图像中。应用膨胀和腐 eclipse 来对图像进行去噪并创建输入 OCR 引擎的最终图像。

import cv2
import numpy as np 
import pytesseract 
pytesseract.pytesseract.tesseract_cmd = 'C:/Program Files (x86)/Tesseract-OCR/tesseract'

d_path = "Test images\\"

img_name = "cropped_12.jpg"

img = cv2.imread(d_path + img_name)  # Reads the image

## Resize image before calculating contour 
height, width = img.shape[:2]
img = cv2.resize(img,(2*width,2*height),interpolation = cv2.INTER_CUBIC)  

img_orig = img.copy()           # Makes copy of original image  

img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)    # Convert to grayscale

#  Apply threshold to get binary image and write to file
_, img = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)


# Edge detection 
edges = cv2.Canny(img,100,200)

# Find contours of mask threshold 
_, contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Find contours associated w/ polygons with 8 sides or more 
cnt_list = []
area_list = [cv2.contourArea(c) for c in contours]
for j in contours:
    poly_pts = cv2.approxPolyDP(j,0.01*cv2.arcLength(j,True),True)
    area = cv2.contourArea(j)
    if (len(poly_pts) > 8) & (area == max(area_list)):
        cnt_list.append(j)

cv2.drawContours(img_orig, cnt_list, -1, (255,0,0), 2)

# Show contours 
cv2.namedWindow('Show',cv2.WINDOW_NORMAL)
cv2.imshow("Show",img_orig)
cv2.waitKey()
cv2.destroyAllWindows()

# Zero pixels outside circle 
mask = np.zeros(img.shape).astype(img.dtype)
cv2.fillPoly(mask, cnt_list, (255,255,255))
mask_inv = cv2.bitwise_not(mask)

a = cv2.bitwise_and(img,img,mask = mask)
wh_back = np.ones(img.shape).astype(img.dtype)*255
b = cv2.bitwise_and(wh_back,wh_back,mask = mask_inv)

res = cv2.add(a,b)

# Get rid of noise 
kernel = np.ones((2, 2), np.uint8)
res = cv2.dilate(res, kernel, iterations=1)
res = cv2.erode(res, kernel, iterations=1)

# Show final image 
cv2.namedWindow('result',cv2.WINDOW_NORMAL)
cv2.imshow("result",res)
cv2.waitKey()
cv2.destroyAllWindows()

当代码运行时,这些是输出的图像: Working

但是,在文本接触圆形边框的情况下,代码假定部分文本是较大轮廓的一部分并忽略最后一个字母。例如: Not working

是否有任何处理步骤可以帮助我绕过这个问题?或者也许是不同的方法?我试过使用 Hough Circle Transforms 来尝试检测边界,但它们非常挑剔,效果不如轮廓线。

我是 OpenCV 和 Python 的新手,所以我们将不胜感激。

最佳答案

如果 Hough 圆变换对您不起作用,我认为您最好的选择是近似边界形状。我知道的最好的方法是:Douglas-Peucker 算法,它可以通过减少图片的周长来简化轮廓。

您可以从 OpenCV 中查看此引用文件,以查看可以应用于寄宿生的后处理类型。他们还提到了 Douglas-Peucker: OpenCV boarder processing

关于python - 从圆形边框内提取文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45579295/

相关文章:

python - 使用一个 sqlite3 查询从两个不同行检索相同的列数据?

c++ - OpenCV:并行 for 循环。我的代码有什么问题?

python - cv.Get2D 颜色坐标

python - 根据一列中与 Pandas 另一列中的引用日期最接近的日期选择行?

python - 适用于 Python 的 MATLAB 'fit' 函数

c++ - 使用 compose 全景图而不使用estimateTransform

OpenCV Haartraining 不会永远完成

c++ - 如何优化以下 C++ 代码片段 - 卷中的零交叉

android - 如何在 OpenCv 中将浮点图像转换为 32 位单 channel ?

python - 为什么我在 Pandas 的时间列中得到 '1900-01-01'