我正在尝试从此收据玩具示例中进行OCR。使用Python 2.7和OpenCV 3.1。

python - Python + OpenCV:OCR图像分割-LMLPHP

灰度+模糊+外部边缘检测+收据中每个区域的分割(例如“类别”,以查看稍后标记的区域-在这种情况下为现金)。

当图像“偏斜”以能够正确转换然后“自动”分割收据的每个部分时,我发现很复杂。

例:

python - Python + OpenCV:OCR图像分割-LMLPHP

有什么建议吗?

下面的代码是在边缘检测之前但在收据就像第一张图像之前要获取的示例。我的问题不是图像到文本。是图像的预处理。

任何帮助都超过赞赏! :)

import os;
os.chdir() # Put your own directory

import cv2
import numpy as np

image = cv2.imread("Rent-Receipt.jpg", cv2.IMREAD_GRAYSCALE)

blurred = cv2.GaussianBlur(image, (5, 5), 0)

#blurred  = cv2.bilateralFilter(gray,9,75,75)

# apply Canny Edge Detection
edged = cv2.Canny(blurred, 0, 20)

#Find external contour

(_,contours, _) = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

最佳答案

可以在pyimagesearch上找到有关您所描述的第一步的出色教程(它们通常都有很好的教程)

简而言之,如Ella所述,您将不得不使用cv2.CHAIN_APPROX_SIMPLE。一种更健壮的方法是使用cv2.RETR_LIST而不是cv2.RETR_EXTERNAL然后对区域进行排序,因为即使在白色背景中/如果页面在背景中刻有更大的形状,它也应能正常工作。

关于您的问题的第二部分,分割字符的一种好方法是使用OpenCV中可用的最大稳定极值区域提取器。我最近在帮助的一个项目中,here提供了CPP的完整实现。 Python的实现方式如下(以下代码适用于OpenCV 3.0+。对于OpenCV 2.x语法,请在线进行检查)

import cv2

img = cv2.imread('test.jpg')
mser = cv2.MSER_create()

#Resize the image so that MSER can work better
img = cv2.resize(img, (img.shape[1]*2, img.shape[0]*2))

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
vis = img.copy()

regions = mser.detectRegions(gray)
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions[0]]
cv2.polylines(vis, hulls, 1, (0,255,0))

cv2.namedWindow('img', 0)
cv2.imshow('img', vis)
while(cv2.waitKey()!=ord('q')):
    continue
cv2.destroyAllWindows()

这给出的输出为

python - Python + OpenCV:OCR图像分割-LMLPHP

现在,要消除误报,您可以简单地循环遍历船体中的点,并计算周长(船体[i]中所有相邻点之间的距离之和,其中,船体[i]是一个凸面船体中所有点的列表) )。如果周边太大,请将其归类为非字符。

由于图像的边框为黑色,因此出现了贯穿图像的诊断线。只要在读取图像后添加以下行即可将其删除(第7行以下)
img = img[5:-5,5:-5,:]

这给出了输出

python - Python + OpenCV:OCR图像分割-LMLPHP

关于python - Python + OpenCV:OCR图像分割,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40443988/

10-10 11:01