
✨专栏介绍: 经过几个月的精心准备,本作者推出全新系列《浅显易懂OCR》专栏,对标最全OCR教程,具体章节如导图所示,将别离从OCR技能开展、方向、概念、算法、论文、数据集等各种视点打开具体介绍。
个人主页: GoAI | 公众号: GoAI的学习小屋 | 交流群: 704932595 |个人简介 : 签约作者、百度飞桨PPDE、领航团团长、开源特训营导师、CSDN、阿里云社区人工智能范畴博客专家、新星计划核算机视觉方向导师等,专心大数据与人工智能常识共享。
文章目录
《浅显易懂OCR》前语常识(二):深度学习根底总结 (✨文末有深度学习总结导图福利!)
《浅显易懂OCR》前语常识(一):机器学习根底总结 (✨文末有机器学习总结导图福利!)
《浅显易懂OCR》第一章:OCR技能导论
《浅显易懂OCR》第二章:OCR技能开展与分类 (本篇)
本篇导读: 本篇为《浅显易懂OCR》第二章:OCR技能开展与分类。本篇首要介绍传统OCR和深度学习OCR办法,从图画处理特征提取、文字检测与辨认等视点打开具体介绍,合作作者总结思维导图,尽或许总结OCR全面常识。
《浅显易懂OCR》第二章:OCR技能开展与分类
OCR技能开展总览
一般来说,OCR技能能够分为传统办法和深度学习办法。 传统办法受限于手艺规划特征的表达能力和处理流程的杂乱性,在杂乱场景下很难到达抱负的文字辨认作用,而依据深度学习OCR运用CNN模型算法替换传统的手动办法,主动检测出文本的类别及方位信息,依据相应方位文本信息主动辨认文本内容,辨认作用更为优秀。
接下来,作者按时刻次序总结了OCR开展流程,具体如下图:

-
在70年代至15年前,传统OCR技能一般选用连通域剖析等办法寻觅潜在文字切分方位,经过必定办法以过切割办法对文字进行切分,然后进行单字辨认。
-
直到16年,深度学习OCR技能获得重大突破,白翔等人提出CRNN网络辨认办法,以序列办法进行辨认,经过选用无需切割办法避免切割过错,成为主流OCR文字辨认办法。
一、传统OCR
传统OCR文字辨认算法首要依据图画处理技能(如投影、膨胀、旋转等)和相关核算机器学习完成图片文本内容提取,其首要运用于布景颜色单一、分辨率高的简略文档图画辨认。
1.1 技能流程:
传统OCR文字辨认是将文本行的字符辨认当作一个多标签使命学习的进程。其辨认进程为图画预处理(五颜六色图画灰度化、二值化处理、图画 改变视点检测、矫正处理等)、版面区分(直线检测、歪斜检测)、字符定位切分、字符 辨认、版面康复、后处理、校对等。

1.1.1 图画预处理
(1)二值化
图画二值化是指将图画像素点的灰度值设为0或255,使出现显着黑白作用。其操作不只削减了数据维度,并且经过排除原图噪声干扰。在某些特定场景中,OCR辨认作用很大程度上取决于该步骤。

(2)歪斜检测与校对
霍夫改换(Hough Transform)
霍夫改换是一种用于在图画中检测几许形状的常见技能,其常见运用是在图画中检测直线。它的根本思想是将图画中的每个像素点转化为参数空间中的曲线,并经过核算参数空间中相交点的数量来确定在原始图画中或许存在的直线。

依据PCA办法
PCA算法需求核算对歪斜视点的分布具有最大影响的特征向量,即分布的主重量,因而首要需求将黑色像素点(即前景)映射为二维向量,使每个像素点与相同坐标的二维向量相匹配,并对每个维度减去其对应强度的均值,然后核算向量调集的协方差矩阵。
1.1.2 传统OCR文本检测和辨认
文本检测和辨认是OCR技能的两个重要核心技能,传统的OCR办法经过针对文本检测和辨认别离规划鲁棒的特征,来进步模型的文字辨认作用。

文本检测:文本检测首要用于定位图片中文本的区域,传统的文本检测办法能够分为依据显著特征的检测办法和依据滑动窗口的检测办法两大类。
文本辨认阶段:文本辨认分为文本二值化、行分段、字符切割、单字辨认、字符矫正等一系列子问题。
总结: 传统文本检测与辨认办法受限于手艺规划特征的表达能力和杂乱的处理流程,关于较为杂乱的图片状况,例如带有畸变以及模糊不清的文本图画,传统文本辨认很难到达抱负的文字辨认作用。
1.2 传统机器学习OCR办法
传统文字辨认的办法一般首要需求文本区域定位,将定位后的歪斜文本进行矫正再切割出单个文字,然后在特征提取阶段运用人工特征或CNN特征进行,再结合分类模型 对单字进行辨认,最终依据核算言语模型(如隐马尔科夫链,HMM)或许规矩进行语义纠错,即言语规矩后处理。
接下来,自己将侧重从特征提取视点和分类模型动身,介绍传统OCR文字辨认技能,让我们快速了解OCR技能的开展。
1.2.1 特征提取办法
(1)依据结构形状的特征提取:
依据结构形状的特征提取首要经过查找概括特征和区域特征进行操作。
1.鸿沟特征法
依据结构形状的特征提取是核算机视觉范畴中的一种办法,它首要用于从图画或其他类型的数据中提取形状学结构和形式。结构形状学是一种数学理论,用于描绘和剖析图画中的形状和结构,包含各类算子(Canny、HOG、Sober、SIFI)等。
各类算子介绍参阅:blog.csdn.net/zaishuiyifa…
- 傅里叶特征算子法
(2)依据几许分布的特征提取:
依据几许分布的特征提取是一种核算机视觉范畴中常用的特征提取办法,它首要用于从图画或其他类型的数据中捕捉几许结构和形状的信息。该办法依据几许学原理,经过剖析图画中的点、线、面等几许形状,从中提取有意义的特征。
1、二维直方图投影法
核算机视觉Opencv库中常用笔直投影和水平投影能够对方针物进行准确投影,以便于后期的切割。其间,水平投影是二维图画在y轴上的投影;笔直投影是二维图画在x轴上的投影。
2. 区域网格投影法
3.模板匹配
模板匹配法是经过核算方针图画与搜索图中所有子图的类似度,其间类似度最大的即认为是最佳待匹配的方位。模板匹配法依据匹配的根本原理演变出多种匹配核算办法,如序贯类似性匹配、间隔改换、最小均方误差等。

总结: 上述特征提取办法在许多核算机视觉使命中都有广泛的运用(方针检测、图画匹配等)。针对杂乱的场景和特征,单独运用依据几许或依据结构形状的特征提取或许不足以满足需求,一般需求与其他特征提取办法结合运用,获取更准确的信息。
参阅学习: Opencv模版匹配
1.2.2 传统分类办法
在字符特征提取后,需求对字符进行辨认,传统机器学习将OCR辨认转化为一个分类使命。 作者这儿总结具体办法及其优缺陷,首要包含以下几类:
(1)支撑向量机
支撑向量机(Support Vector Machine,SVM)是依据核算学理论的一种分类辨认算法。支撑向量机分类算法不只关于小样本的状况具有较好的分类作用,并且对高维和线性不可分的问题进行了很好的处理,这是该算法的首要优。
缺陷:例如核函数的选择,以及算法的实时性较差等问题。
(2)贝叶斯分类算法
贝叶斯分类算法(Bayes)首要原理是经过Bayes定理对未知样本进行预测,并核算样本进行各个类别的或许性,最终经过概率核算对图画完成分类。
长处:贝叶斯分类办法的首要长处在于鲁棒性强,稳定性好;
缺陷:模型根底假定不同属性间的概率独立,即彼此不影响。因而要考虑运用场景。
(3)K近邻算法
K近邻算法是典型无监督分类算法,其原理依据给定的练习数据集,对新输入实例,在练习数据会集找到间隔最近的K个样本点。经过这K个样本点所属类别的多数投票来决定所属类别。
K近邻算法将新的数据点归类到与其最接近的K个练习数据点中所属类别中。
KNN长处:简略易懂、易于完成、不需求练习阶段等。适用各种数据类型,特别是在数据特征较少或许数据之间有显着的部分结构时体现较好。
KNN缺陷:核算杂乱度较高,特别是在处理大规模数据集时。
(4)多层感知机
多层感知机(MLP)是一种前馈神经网络–依据多层节点的人工神经网络模型,是深度学习的根本组成部分之一,被广泛用于处理分类和回归等问题。
MLP长处:经过增加躲藏层和节点的数量处理杂乱的非线性问题,进步模型的体现能力。
MLP缺陷:练习和调整需求大量的数据和核算资源,易过拟合。
(5)神经网络算法
神经网络算法常用在处理分类和回归问题。OCR技能中也广泛运用了依据神经网络的算法,字符图画在运用神经网络分类器进行辨认时,依据网络的输入层的不同能够分为两种状况:
一是将二维的字符图画直接作为网络的输入,将图画的各个像素点作为节点进行全衔接,这种办法能够完成较高的辨认正确率,且抗干扰能力强,但会花费较长的时刻练习网络;
二是对字符图画进行特征提取,然后将提取到字符特征信息作为祌经网络输入进行网络练习,可有用削减网络练习所需的时刻,但字符辨认正确率的凹凸取决于字符特征信息提取的有用程度。
总结: 传统OCR办法是依据投影法、连通域剖析法等办法对文本行进行字符切割,运用单字分类器对切割好的字符,或运用滑动窗口按必定步长滑窗,运用单字分类器对滑动窗口内的字符进行辨认,但是这些办法的准确率有限,其首要运用于布景颜色单一、尤其是在杂乱场景辨认下,辨认作用不如依据深度学OCR习办法。
材料推荐:传统OCR学习
二、深度学习OCR
近年来随着深度学习技能的飞速开展,OCR技能逐渐由手艺规划文本特征练习模型的办法演变成运用CNN深度卷积神经网络模型进行图画主动特征提取,在文字辨认作用上也有了较大的提高。
2.1 技能流程:
深度学习图画文字辨认流程包含:输入图画、深度学习文字区域检测、预处理、特征提取、深度学习辨认器、深度学习后处理等。

- 图画预处理: 是对输入的图画进行一些处理操作,以便于后续的文字检测和辨认。首要包含灰度化、二值化、降噪、歪斜校对、归一化等操作。
- 文字检测: 是将图画中的文字区域定位出来,并给出其方位和方向的信息。首要分为依据回归的办法和依据切割的办法。常用的模型有CTPN、EAST、DBNet等。
- 文字辨认: 是对上述检测出的文字区域进行辨认,将图画中的文字转化为可读的文本信息。首要包含单字分类、整词分类和整词辨认三种类型,常用的模型有CRNN、ASTER等。
- 后处理: 是对辨认成果进行优化和校对,以进步准确率和可读性。首要包含运用言语模型、字典、规矩等办法来纠正过错或存在歧义的辨认成果。
- 别的,还能够运用版面剖析、表格辨认等办法来复原原始文档的排版和结构。
2.2 深度学习OCR文字检测与文字辨认
OCR辨认算法可分为两阶段算法和端对端的算法。两阶段OCR算法分为两部分,文本检测和文本辨认算法,文字检测算法从图画得到文本行检测框,然后辨认算法去辨认文本框中内容。
同时,按数据集分类辨认:能够分为不规矩文本及规矩文本辨认,按处理场景辨认可分为简略运用场景和杂乱场景辨认,其间,端到端算法能够处理杂乱场景辨认。

2.2.1 深度学习文字检测
(1)深度学习文字检测模型开展:

(2)场景文字检测办法分类
从结构动身,文字检测技能能够分为自顶向上和自顶向上。而从辨认办法上,首要分为依据回归和依据切割两种检测办法。

2.2.2 深度学习文字辨认
(1) 深度学习文字辨认算法流程
目前主流的深度学习辨认算法通用框架包含图画预处理(校对改变)、视觉特征提取、序列提取及预测等模块,其流程如图所示:

(2)文字辨认模型开展:

(3)场景文字辨认办法分类:

深度学习OCR办法分类总结:
深度学习OCR辨认办法首要包含依据CTC、依据Attention、依据Transformer、依据切割及端到端辨认等几种办法。其间文字辨认主流办法有CRNN、ASTER、SRN、ABINet等。
具体分类及论文参阅下表:
算法类别 | 首要思路 | 首要论文 |
---|---|---|
传统算法 | 滑动窗口、字符提取、动态规划 | – |
ctc | 依据ctc的办法,序列不对齐,更快速辨认 | CRNN, Rosetta |
Attention | 依据attention的办法,运用于非常规文本 | RARE, DAN, PREN |
Transformer | 依据transformer的办法 | SRN, NRTR, Master, ABINet |
校对 | 校对模块学习文本鸿沟并校对成水平方向 | RARE, ASTER, SAR |
切割 | 依据切割的办法,提取字符方位再做分类 | Text Scanner, Mask TextSpotter |
OCR辨认算法总结:
- 依据CTC辨认算法首要CRNN,CTC损失处理序列对齐问题,推理速度快,辨认精度高。
- 依据Attention辨认算法首要有ASTER、RAEN等,结合注意力机制根本思想让系统学会注意力重视重点信息,同时疏忽无关信息,有用提高精度。
- 端到端辨认首要有STN-OCR、FOTS、ABCnet、MORAN等办法,无需检测后在辨认,能够完成端到端辨认。
注:文字辨认算法具体介绍建第四章。
2.3 端到端天然场景检测和辨认办法:
不同于两阶段算法,端对端OCR算法选用单阶段,仅运用一个算法完成上述文字检测与辨认,因而需求规划一个同时具有检测单元和辨认模块的模型,经过共享两者的卷积特征进行练习,端对端辨认模型更小,速度更快。
深度学习端到端文本辨认具有代表性的办法大致可分为两类:
-
针对平直文本或歪斜文本特色,运用端到端规矩辨认,代表算法有FOTS、TextSpotter等。
-
针对曲折、变形、歪斜文本特色,运用端到端恣意形状辨认。代表算法有Mask TextSpotter系列、ABCNet系列、PGNet、PAN++等。

总结: 端到端规矩辨认处理了平直文或歪斜文本的检测和辨认,但在印证、街景等不同天然场景中存在大量曲折、变形特色。因而,在运用端到端规矩文本辨认前需求校对,或直接运用端到端恣意形状文本辨认算法(如ABCnet系列)。
三、依据OpenCV的传统OCR辨认实战
import cv2
import numpy as np
import argparse
import imutils
from imutils import contours
import pytesseract
from PIL import Image
import os
def ShowImage(name, image):
cv2.imshow(name, image)
cv2.waitKey(0) # 等待时刻,0表明恣意键退出
cv2.destroyAllWindows()
def order_points(pts):
# 四个点坐标
rect = np.zeros((4,2), dtype="float32")
# 按次序找到坐标,别离左上,右上,右下,左下
# 核算左上、右下
s = pts.sum(axis=1)
rect[0] = pts[np.argmin(s)]
rect[2] = pts[np.argmax(s)]
# 核算右上和左下
diff = np.diff(pts, axis=1)
rect[1] =pts[np.argmin(diff)]
rect[3] = pts[np.argmax(diff)]
return rect
def four_point_transform(image, pts):
# 获取输入坐标点
rect = order_points(pts)
(tl, tr, br, bl) = rect
# 核算输入的W和h值
widthA = np.sqrt(((br[0] - bl[0])**2) + ((br[1] - bl[1])**2))
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max(int(widthA), int(widthB))
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxheight = max(int(heightA), int(heightB))
# 改换后的对应坐标方位
dst = np.array([
[0,0],
[maxWidth-1, 0],
[maxWidth-1,maxheight-1],
[0, maxheight-1]
], dtype="float32")
# 核算改换矩阵
M = cv2.getPerspectiveTransform(rect, dst)
warp = cv2.warpPerspective(image, M, (maxWidth, maxheight))
return warp
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
dim = None
(h,w)=image.shape[:2]
if width is None and height is None:
return image
if width is None:
r=height/float(h)
dim=(int(w*r), height)
else:
r=width/float(w)
dim=(width, int(h*r))
resized = cv2.resize(image, dim,interpolation=inter)
return resized
image = cv2.imread('ocr1.png')
ratio = image.shape[0]/500 # ratio ,是图画转化的份额,稍后会将图画置为500高度的巨细,,最终面在转化后需求转化为原来巨细
orig = image.copy() # orig,先仿制一个原图出来,后面在处理时,image会改变
image = resize(image, height=500) # 将图画变为高500的图画
#图画预处理
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 转化为灰度图
gray = cv2.GaussianBlur(gray, (5,5), 0) # 经过高斯滤波去除噪声
edged = cv2.Canny(gray, 75, 200) # 检测边缘
ShowImage('edged', edged)
# 概括检测
cnts,his = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:5] # 按概括面积进行排列,取前面5个概括
# 遍历每一个概括
for c in cnts:
# 核算概括近似
peri = cv2.arcLength(c,True)
# c表明输入的点集
# epsilon表明从原始概括到近似概括的最大间隔,它是一个准确度参数
# True表明关闭的
approx = cv2.approxPolyDP(c,0.02*peri, True)
# 四个点的时分就拿出来
if len(approx) == 4:
screecnt = approx
break
# 画图
cv2.drawContours(image, [screecnt], -1, (0,0,255), 2)
ShowImage('image',image)
# 透视改换,将输入的四个点,已知4个方针点,经过矩阵改换,图画旋转到方针方位
warped = four_point_transform(orig, screecnt.reshape(4,2)*ratio)
ShowImage('warped', warped)
# 二值处理
warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY) # 转化为灰度图
ref = cv2.threshold(warped, 100, 255, cv2.THRESH_BINARY)[1] # 图画二值化
ShowImage('binary', ref)
# 用OCR工具包test
filename = "{}.png".format(os.getpid())
cv2.imwrite(filename, ref)
text = pytesseract.image_to_string(Image.open(filename))
print(text)
os.remove(filename)
ShowImage('image', ref)
完成作用:


