OCR文字识别笔记总结
OCR的全称是Optical Character Recognition,光学字符识别技术。目前应用于各个领域方向,甚至这些应用就在我们的身边,比如身份证的识别,交通路牌的识别,车牌的自动识别等等。本文就学习一下基于开源软件和大厂服务的文字识别效果。
关于ocr的简介,请参考博客:https://www.cnblogs.com/wj-1314/p/9446756.html
刚入门不久,而且还是自己摸着石头过河,所以学的知识深一点,浅一点的,博客里面记录的是自己学习的过程,希望记录自己的学习之路,回头看也好回顾。
在去年八九月份的时候,学习了好多关于OCR文字识别的文章,并做了笔记,如下。那现在对一些简单快速识别的接口做下笔记。
方案1:基于开源软件Tesseract实现
有些时候使用开源软件比较方便,当然目前最有名的就是tesseract,目前由谷歌在进行维护,貌似使用的还是传统机器学习的方式。
那这里想了解,可以参考我写过的文章:
2,深入学习Tesseract-ocr识别中文并训练字库的方法
方案2:百度文字识别接口服务
下面主要针对Python开发者,描述百度文字识别接口服务的相关技术内容。OCR接口提供了自然场景下整图文字检测、定位、识别等功能。文字识别的结果可以用于翻译、搜索、验证码等代替用户输入的场景。
首先我们可以找一个产品服务的定价单:
可以看到,倘若你的服务只有偶尔用一次,完全可以使用这种体验型的免费服务。如果一天需要调用一万次,那么一个月基本的花费在5w左右——成本还是很高的,所以很多商用的场景大多数都采用自主研发的方法来做。
下面学习一下百度API的SDK软件开发工具包(Software Development Kit)的使用。
1,百度AipOcr接口能力
2,安装接口模型
pip install baidu-aip
3,新建AipOcr
AipOcr是OCR的Python SDK客户端,为使用OCR的开发人员提供了一系列的交互方法。
参考如下代码新建一个AipOcr:
from aip import AipOcr """ 你的 APPID AK SK """
APP_ID = '你的 App ID'
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key' client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
在上面代码中,常量APP_ID
在百度云控制台中创建,常量API_KEY
与SECRET_KEY
是在创建完毕应用后,系统分配给用户的,均为字符串,用于标识用户,为访问做签名验证,可在AI服务控制台中的应用列表中查看。
上面代码块里APP_ID 、API_KEY、SECRET_KEY 三个值对应在http://console.bce.baidu.com/ai/#/ai/ocr/app/list 这里找到,需要用百度账号登录,然后创建一个应用,如下图:
4,配置AipOcr
如果用户需要配置AipOcr的网络请求参数(一般不需要配置),可以在构造AipOcr之后调用接口设置参数,目前只支持以下参数:
5,通用文字识别接口说明
我们向服务请求识别某张图中的所有文字
""" 读取图片 """
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read() image = get_file_content('example.jpg') """ 调用通用文字识别, 图片参数为本地图片 """
client.basicGeneral(image); """ 如果有可选参数 """
options = {}
options["language_type"] = "CHN_ENG"
options["detect_direction"] = "true"
options["detect_language"] = "true"
options["probability"] = "true" """ 带参数调用通用文字识别, 图片参数为本地图片 """
client.basicGeneral(image, options) url = "https//www.x.com/sample.jpg" """ 调用通用文字识别, 图片参数为远程url图片 """
client.basicGeneralUrl(url); """ 如果有可选参数 """
options = {}
options["language_type"] = "CHN_ENG"
options["detect_direction"] = "true"
options["detect_language"] = "true"
options["probability"] = "true" """ 带参数调用通用文字识别, 图片参数为远程url图片 """
client.basicGeneralUrl(url, options)
6,通用文字识别 请求参数详情
7,通用文字识别 返回数据参数详情
8, 通用文字识别返回示例
{
"log_id": 2471272194,
"words_result_num": 2,
"words_result":
[
{"words": " TSINGTAO"},
{"words": "青島睥酒"}
]
}
9,最终代码:
# -*- coding: UTF-8 -*-
from aip import AipOcr # 定义常量
APP_ID = '14544448'
API_KEY = 'yRZGUXAlCd0c9vQj1kAjBEfY'
SECRET_KEY = 'sc0DKGy7wZ9MeWFGZnbscbRyoDB2IQlj' # 初始化AipFace对象
client = AipOcr(APP_ID, API_KEY, SECRET_KEY) # 读取图片
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read() image = get_file_content('binary_best.jpg')
# 调用通用文字识别, 图片为本地图片
res=client.general(image)
print(res) for item in res['words_result']:
print(item['words'])
10,识别结果
识别图片1为:
识别结果1为:
{'log_id': 599780865793529561, 'words_result_num': 7, 'words_result':
[{'location': {'width': 321, 'top': 6, 'left': 2, 'height': 23}, 'words': '山有
木兮木有枝,心悦君兮君不知。'}, {'location': {'width': 143, 'top': 46, 'left': 2,
'height': 19}, 'words': '出自先秦的《越人歌》'}, {'location': {'width': 146,
'top': 84, 'left': 1, 'height': 18}, 'words': '今夕何夕兮,拳舟中流'}, {'location':
{'width': 181, 'top': 112, 'left': 1, 'height': 19}, 'words': '今日何日兮,得与王
子同舟。'}, {'location': {'width': 152, 'top': 141, 'left': 1, 'height': 17}, 'wo
rds': '蒙羞被好兮,不訾诟耻。'}, {'location': {'width': 181, 'top': 168, 'left': 1,
'height': 19}, 'words': '心几烦而不绝兮,得知王子。'}, {'location': {'width': 222,
'top': 195, 'left': 2, 'height': 20}, 'words': '山有木兮木有枝,心悦君兮君不知。'}]} 山有木兮木有枝,心悦君兮君不知。
出自先秦的《越人歌》
今夕何夕兮,拳舟中流
今日何日兮,得与王子同舟。
蒙羞被好兮,不訾诟耻。
心几烦而不绝兮,得知王子。
山有木兮木有枝,心悦君兮君不知。 Process finished with exit code 0
识别图片2为:
识别结果2为:
{'log_id': 7769540578562875641, 'words_result_num': 7, 'words_result':
[{'location': {'width': 44, 'top': 20, 'left': 39, 'height': 21}, 'words': 'GTIN'},
{'location': {'width': 54, 'top': 18, 'left': 329, 'height': 20}, 'words': 'Count'},
{'location': {'width': 139, 'top': 45, 'left': 37, 'height': 21}, 'words': '001
90198720566'}, {'location': {'width': 73, 'top': 76, 'left': 36, 'height': 24},
'words': 'SSCC18:'}, {'location': {'width': 69, 'top': 78, 'left': 329, 'height':
21}, 'words': 'Product'}, {'location': {'width': 178, 'top': 104, 'left': 35,
'height': 21}, 'words': '008859090495625554'}, {'location': {'width': 108,
'top': 104, 'left': 328, 'height': 22}, 'words': 'MRJP2CH/A'}]} GTIN
Count
00190198720566
SSCC18:
Product
008859090495625554
MRJP2CH/A
参考:http://ai.baidu.com/docs#/OCR-Python-SDK/e4ddca43
方案3:KNN实现简单的OCR
这次在网上看到KNN在ocr的识别,非常想尝试一下,原文作者说KNN在ocr的识别过程中能发挥作用的地方就是将图像中的文字转化为文本格式,而OCR的其他部分,比如图像预处理,二值化等操作将丢给OpenCV去操作。
代码地址:github:https://github.com/hahahaha1997/OCR
1,训练集简介
由于我们采用的是KNN来转换图像中的文字为文本格式,需要一个庞大的手写字符训练集来支撑我们的算法。这里我使用的是《机器学习实战》2.3实例:手写识别系统中使用的数据集,其下载地址为:https://www.manning.com/books/machine-learning-in-action,在Source Code\Ch02\digits\trainingDigits中的两千多个手写字符既是我所使用的训练集。
这个训练集配合上它所提供的测试集,提供了一个准确度非常高的分类器:
训练集是由0~9十个数字组成的,每个数字有两百个左右的训练样本。所有的训练样本统一被处理为一个32*32的0/1矩阵,其中所有值为1的连通区域构成了形象上的数字,如下所示:
所以,在构造我们的测试集的时候,所有的手写数字图片必须被处理为这样的格式才能够使得分类算法正确地进行,这也是KNN的局限所在。
2、构建测试集
上面已经提到,要想算法正确地进行,测试集的样式应该和训练集相同,也就是说我们要把一张包含有手写数字的图像,转换为一个32*32的0/1点阵。
测试集使用我自己手写的10个数字:
这里存在一个非常大的问题:这个数据集的作者是土耳其人,他们书写数字的习惯和我们有诸多不同,比如上面的数字4和数字8,下面这样子的数字就无法识别:4/8。哈哈,也就是说它连印刷体都无法识别,这是这个训练集的一大缺陷之一。
1)图像预处理
图像预处理的过程是一个数字图像处理(DIP)的过程,观察上面的10个数字,可以发现每张图像的大小/对比度的差距都非常大,所以图像预处理应该消除这些差距。
第一步是进行图像的放大/缩小。由于我们很难产生一个小于32*32像素的手写数字图像,所以这里主要是缩小图像:
import cv2
def readImage(imagePath):
image = cv2.imread(imagePath,cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image,(32,32),interpolation = cv2.INTER_AREA)
return image
这里我没有去实现图像重采样的方法,而是采用的OpenCV,通过area来确定取样点的灰度值(推荐用bicubic interpolation,对应的插入函数应该是INTER_CUBIC),在读入图像的时候读入方式位IMRAD_GRAYSCALE,因为我们需要的是识别手写字符,灰度图对比彩色图能更好的突出重点。
进行图像的缩放是不够的,因为观察上面的图片可以发现:拍摄环境对于对比度的影响非常大,所以我们应该突出深色区域(数字部分),来保证后面的工作顺利进行,这里采用的是伽马变换(也可以采用对数变换):
def imageGamma(image):
for i in range(32):
for j in range(32):
image[i][j]=3*pow(image[i][j],0.8)
return image
2)图像二值化
缩小/放大后的图像已经是一个32*32的图像了,下一步则是将非数字区域填充0,数字区域填充1,这里我采用的是阈值二值化处理:
def imageThreshold(image):
ret,image = cv2.threshold(image,150,255,cv2.THRESH_BINARY)
return image
经过二值化处理,数字部分的灰度值应该为0,而非数字部分的连通区域的灰度值应该为255,如下所示:
3)去噪
图像去噪的方式有很多种,这里建立使用自适应中值滤波器进行降噪,因为我们的图像在传输过程中可能出现若干的椒盐噪声,这个噪声在上述的二值化处理中有时候是非常棘手的。
到目前为止,一副手机摄像的手写数字图像就可以转换为一个32*32的二值图像。
4)生成训练样本
如何将这个32*32的二值图像转换为0/1图像,这个处理非常简单:
def imageProcess(image):
with open(r'F:\Users\yang\PycharmProjects\OCR_KNN\testDigits\6_0.txt','w+') as file:
for i in range(32):
for j in range(32):
if image[i][j] == 255:
file.write('0')
else:
file.write('1')
file.writelines('\n')
这里我的代码在扫描这个图像的同时,将其保存为一个训练样本,命名和训练集的明明要求一样为N_M.txt,其中N代表这个训练样本的实际分类是什么数字,M代表这是这个数字的第几个样本。这里对图像进行灰度变换已经是多此一举了,我所需要的是0/1矩阵而非一个0/1图像,所以在扫描过程中一并生成训练样本更加省时直观。
5)形成训练集
上面的示例只是生成一个图像的训练样本的,而实际上我们往往需要一次性生成一个训练集,这就要求这个图像预处理、二值化并且生成0/1矩阵的过程是自动的:
from os import listdir
def imProcess(imagePath):
testDigits = listdir(imagePath)
for i in range(len(testDigits)):
imageName = testDigits[i]#图像命名格式为N_M.png,NM含义见4)生成训练样本
#imageClass = int((imageName.split('.')[0]).split('_')[0])#这个图像的数字是多少
image = cv2.imread(imageName,cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image, (32, 32), interpolation=cv2.INTER_AREA)
ret, image = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY)
with open(r'F:\Users\yang\PycharmProjects\OCR_KNN\testDigits\\'+imageName.split('.')[0]+'.txt','w+') as file:
for i in range(32):
for j in range(32):
if image[i][j] == 255:
file.write('0')
else:
file.write('1')
file.writelines('\n')
这个函数将imagePath文件夹中所有的N_M命名的手写数字图像读取并经过预处理、二值化、最后保存为对应的0/1矩阵,命名为N_M.txt,这就构成一个训练集了。
3、构建分类器
分类器如下:
def classify(vector,dataSet,labels,k):
distance = sqrt(abs(((tile(vec,(dataSet.shape[0],1)) - dataSet) ** 2).sum(axis = 1))); #计算距离
sortedDistance = distance.argsort()
dict={}
for i in range(k):
label = labels[sortedDistance[i]]
if not label in dict:
dict[label] = 1
else:
dict[label]+=1
sortedDict = sorted(dict,key = operator.itemgetter(1),reverse = True)
return sortedDict[0][0] def dict2list(dic:dict):#将字典转换为list类型
keys=dic.keys()
values=dic.values()
lst=[(key, value)for key,value in zip(keys,values)]
return lst
distance的计算和dict2list函数的详解在上一节,戳上面的classify既可以跳转过去。
分类器已经构建完成,下一步是提取每一个测试样本,提取训练集,提取label的过程:(这个过程大部分用的是《机器学习实战》中的代码,对于难以理解的代码在下文中做了解释:)
1)读取0/1矩阵文件:
def img2vector(filename):
returnvec = numpy.zeros((1,1024))
file = open(filename)
for i in range(32):
line = file.readline()
for j in range(32):
returnvec[0,32*i+j] = int(line[j])
return returnvec
这里要注意:构造一个32*32的全零矩阵的时候,应该是numpy.zeros((1,1024)),双层括号!双层括号!双层括号!代表构造的是一个二维矩阵!
2)读取训练集和测试集并求解准确率:
def handWritingClassifyTest():
labels=[]
trainingFile = listdir(r'F:\Users\yang\PycharmProjects\OCR_KNN\trainingDigits')
m = len(trainingFile)
trainingMat = numpy.zeros((m,1024))
for i in range(m):
file = trainingFile[i]
filestr = file.strip('.')[0]
classnum = int(filestr.strip('_')[0])
labels.append(classnum)
trainingMat[i,:] = img2vector('trainingDigits/%s' % file)
testFileList = listdir(r'F:\Users\yang\PycharmProjects\OCR_KNN\testDigits')
error = 0.0
testnum = len(testFileList)
for i in range(testnum):
file_test = testFileList[i]
filestr_test = file_test.strip('.')[0]
classnum_test = int(filestr_test.strip('_')[0])
vector_test = img2vector('testDigits/%s'%file_test)
result = classify(vector_test,trainingMat,labels,1)
if(result!=classnum_test):error+=1.0
print("准确率:%f"%(1.0-(error/float(testnum))))
代码其实没有很难懂的地方,主要任务就是读取文件,通过img2vctor函数转换为矩阵,还有切割文件名获取该测试样本的类别和该训练样本的类别,通过对比获得准确率。
3、使用分类器
现在为止,我们的分类器已经构建完成,下面就是测试和使用阶段:
1)测试《机器学习实战》中给出的训练集:
2)测试手写训练集:
果然学不出来大佬写字,附上几张无法识别的0/1数字矩阵:(0,4,6无法识别的原因是比划太细哈哈,8无法识别的原因……太端正了吧)
4、完整代码:
from os import listdir
import numpy
import operator
import cv2 def imProcess(imagePath):
testDigits = listdir(imagePath)
for i in range(len(testDigits)):
imageName = testDigits[i]#图像命名格式为N_M.png,NM含义见4)生成训练样本
#imageClass = int((imageName.split('.')[0]).split('_')[0])#这个图像的数字是多少
image = cv2.imread(imageName,cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image, (32, 32), interpolation=cv2.INTER_AREA)
ret, image = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY)
with open(r'F:\Users\yang\PycharmProjects\OCR_KNN\testDigits\\'+imageName.split('.')[0]+'.txt','w+') as file:
for i in range(32):
for j in range(32):
if image[i][j] == 255:
file.write('0')
else:
file.write('1')
file.writelines('\n') def img2vector(filename):
returnvec = numpy.zeros((1,1024))
file = open(filename)
for i in range(32):
line = file.readline()
for j in range(32):
returnvec[0,32*i+j] = int(line[j])
return returnvec def handWritingClassifyTest():
labels=[]
trainingFile = listdir(r'F:\Users\yang\PycharmProjects\OCR_KNN\trainingDigits')
m = len(trainingFile)
trainingMat = numpy.zeros((m,1024))
for i in range(m):
file = trainingFile[i]
filestr = file.strip('.')[0]
classnum = int(filestr.strip('_')[0])
labels.append(classnum)
trainingMat[i,:] = img2vector('trainingDigits/%s' % file)
testFileList = listdir(r'F:\Users\yang\PycharmProjects\OCR_KNN\testDigits')
error = 0.0
testnum = len(testFileList)
for i in range(testnum):
file_test = testFileList[i]
filestr_test = file_test.strip('.')[0]
classnum_test = int(filestr_test.strip('_')[0])
vector_test = img2vector('testDigits/%s'%file_test)
result = classify(vector_test,trainingMat,labels,1)
if(result!=classnum_test):error+=1.0
print("准确率:%f"%(1.0-(error/float(testnum)))) def classify(inX,dataSet,labels,k):
size = dataSet.shape[0]
distance = (((numpy.tile(inX,(size,1))-dataSet)**2).sum(axis=1))**0.5
sortedDistance = distance.argsort()
count = {}
for i in range(k):
label = labels[sortedDistance[i]]
count[label]=count.get(label,0)+1
sortedcount = sorted(dict2list(count),key=operator.itemgetter(1),reverse=True)
return sortedcount[0][0] def dict2list(dic:dict):#将字典转换为list类型
keys=dic.keys()
values=dic.values()
lst=[(key, value)for key,value in zip(keys,values)]
return lst # def imProcess(image):
# image = cv2.resize(image, (32, 32), interpolation=cv2.INTER_AREA)
# ret, image = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY)
# cv2.imshow('result',image)
# cv2.waitKey(0)
# with open(r'F:\Users\yang\PycharmProjects\OCR_KNN\testDigits\6_0.txt','w+') as file:
# for i in range(32):
# for j in range(32):
# if image[i][j] == 255:
# file.write('0')
# else:
# file.write('1')
# file.writelines('\n') # iamge = cv2.imread(r'C:\Users\yang\Desktop\6.png',cv2.IMREAD_GRAYSCALE)
# image = imProcess(iamge)
imProcess(r'F:\Users\yang\PycharmProjects\OCR_KNN\testDigits')
handWritingClassifyTest()
5、总结
KNN还是不适合用来做OCR的识别过程的,虽然《机器学习实战》的作者提到这个系统是美国的邮件分拣系统实际运行的一个系统,但是它肯定无法高准确率地识别中国人写的手写文字就对了,毕竟中国有些地方的“9”还会写成“p”的样子的。这一节主要是将KNN拓展到实际运用中的,结合上一节的理论,KNN的执行效率还是太低了,比如这个系统,要识别一个手写数字,它需要和所有的训练样本做距离计算,每个距离计算又有1024个(a-b)²,还有运行效率特别低下的sqrt(),如果是一个非常大的测试集,需要的时间就更加庞大,如果训练集非常庞大,在将0/1矩阵读入内存中的时候,内存开销是非常巨大的,所以整个程序可能会非常耗时费力。不过KNN仍旧是一个精度非常高的算法,并且也是机器学习分类算法中最简单的算法之一。
KNN实现OCR的转载地址:https://www.cnblogs.com/DawnSwallow/p/9440516.html
知识储备:使用Python写入数据到Excel文件中
1 安装XlsxWriter
python XlsxWriter模块创建aexcel表格,生成的文件后缀名为.xlsx,最大能够支持1048576行数据,16384列数据
pip install XlsxWriter
2 在Excel写数据
# 建立文件
workbook = xlsxwriter.Workbook("text.xlsx")
# 可以制定表的名字
# worksheet = workbook.add_worksheet('text')
worksheet = workbook.add_worksheet() # 设置列宽
# worksheet.set_column('A:A',10)
# 设置祖体
bold = workbook.add_format({'bold':True})
# 定义数字格式
# money = workbook.add_format({'num_format':'$#,##0'}) # 写入带粗体的数据
worksheet.write('A1','data',bold)
worksheet.write('B1','work')
'''
worksheet.write(0, 0, 'Hello') # write_string()
worksheet.write(1, 0, 'World') # write_string()
worksheet.write(2, 0, 2) # write_number()
worksheet.write(3, 0, 3.00001) # write_number()
worksheet.write(4, 0, '=SIN(PI()/4)') # write_formula()
worksheet.write(5, 0, '') # write_blank()
worksheet.write(6, 0, None) # write_blank()
''' worksheet.write('A3',15)
worksheet.write('B3',20)
worksheet.write('C3',44)
worksheet.write('D3',36)
# xlsx计算数据
worksheet.write('E3','=SUM(A3:D3)') '''
建立Chart对象: chart = workbook.add_chart({type, 'column'})
Chart: Area, Bar, Column, Doughnut, Line, Pie, Scatter, Stock, Radar
将图插入到sheet中: worksheet.insert_chart('A7', chart)
''' # 定义插入的图标样式
chart = workbook.add_chart({"type":'column'}) headings = ['a','b','c']
data = [
[1,2,3,4,5],
[2,4,6,8,10],
[3,6,9,12,15],
]
# 按行插入数据
worksheet.write_row('A4',headings)
# 按列插入数据
worksheet.write_column('A5',data[0])
worksheet.write_column('B5',data[1])
worksheet.write_column('C5',data[2])
# 图行的数据区
# name:代表图例名称;
# categories:是x轴项,也就是类别;
# values:是y轴项,也就是值;
chart.add_series({
'name':'=Sheet1!$B$4',
'categories':'=Sheet1!$A$5:$A$9',
'values':'=Sheet1!$B$5:$B$9',
})
chart.add_series({
'name':['Sheet1', 3, 2],
'categories':['Sheet1', 4, 0, 8, 0],
'values':['Sheet1', 4, 2, 8, 2],
})
# 图形的标题
chart.set_title ({'name': 'Percent Stacked Chart'})
# 图形X轴的说明
chart.set_x_axis({'name': 'Test number'})
# 图形Y轴的说明
chart.set_y_axis({'name': 'Sample length (mm)'})
# 设置图表风格
chart.set_style(11)
# 插入图形,带偏移
worksheet.insert_chart('D12',chart,{'x_offset': 25, 'y_offset': 10}) workbook.close()
OCR文字识别笔记总结的更多相关文章
- 小白学Python——用 百度AI 实现 OCR 文字识别
百度AI功能还是很强大的,百度AI开放平台真的是测试接口的天堂,免费接口很多,当然有量的限制,但个人使用是完全够用的,什么人脸识别.MQTT服务器.语音识别等等,应有尽有. 看看OCR识别免费的量 快 ...
- Android OCR文字识别 实时扫描手机号(极速扫描单行文本方案)
身份证识别:https://github.com/wenchaosong/OCR_identify 遇到一个需求,要用手机扫描纸质面单,获取面单上的手机号,最后决定用tesseract这个开源OCR库 ...
- 有什么OCR文字识别软件好用?
OCR文字识别是指:对文本资料进行扫描,然后对图像文件进行分析处理,最后获取文字以及版面信息的过程.对于许多学生党而言,一款好用的文字识别软件,能节省很多抄笔记的时间,而对于许多处理文字内容的白领而言 ...
- 怎么给OCR文字识别软件重编文档页面号码
ABBYY FineReader Pro for Mac OCR文字识别软件处理文档时,在FineReader文档中,页面的加载顺序即是页面的导入顺序,完成导入之后,文档的所有页面均会被编号,各编号会 ...
- 对OCR文字识别软件的扫描选项怎么设置
说到OCR文字识别软件,越来越多的人选择使用ABBYY FineReader识别和转换文档,然而并不是每个人都知道转换质量取决于源图像的质量和所选的扫描选项,今天就给大家普及一下这方面的知识. ABB ...
- 怎么提高OCR文字识别软件的识别正确率
在OCR文字识别软件当中,ABBYY FineReader是比较好用的程序之一,但再好的识别软件也不能保证100%的识别正确率,用户都喜欢软件的正确率高一些,以减轻识别后修正的负担,很多用户也都提过这 ...
- OCR文字识别软件许可文件被误删了怎么办
使用任何一款软件,都会有误操作的情况发生,比如清理文件时一不小心删除了许可文件,对于ABBYY FineReader 12这样一款OCR文字识别软件,因失误错误删除了许可文件该怎么办呢?今天就来给大家 ...
- 怎么给OCR文字识别软件设置正确的扫描分辨率
ABBYY FineReader 12是一款专业的OCR文字识别软件,可快速方便地将扫描纸质文档.PDF文件和数码相机的图像转换成可编辑.可搜索的文本,不仅支持对页扫描,还支持多页扫描,扫描分辨率的选 ...
- 怎么使用OCR文字识别软件图像压缩功能
ABBYY FineReader是一款非常实用的OCR文字识别软件,在使用ABBYY FineReader保存文档时可以选择图像格式和压缩方法,通过图像压缩可以减小文件的大小,图像压缩方法视压缩率和数 ...
随机推荐
- 解决WPF的ScrollViewer在使用触摸屏时,滑到尽头窗口抖动的情况
原文:解决WPF的ScrollViewer在使用触摸屏时,滑到尽头窗口抖动的情况 wpf的ScrollViewer在触摸条件下 默认在尽头时会有一个窗口一起被拖动的FeedBack,但对用户的交互很不 ...
- jquery获取选中的值和设置单选扭选中
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- python3 提示No module named _sqlite3
yum install sqlite-devel 下载python3.6.3 重新编译安装 ./configure --enable-loadable-sqlite-extensions & ...
- miniui处理多重子表级联,一次性提交多表数据的ui要点
在一个ui界面上 有a,b,c三个表 a表只有一条记录,b表有多条记录,c表有多条记录 b是a的子表,c是b的子表 都是一对多关系 一次性下载相关联的c表记录 然后mini-datagrid采用cli ...
- PowerDesigner 在通过jdbc连接数据库时 Could not Initialize JavaVM!
最近用到PowerDesigner的逆向工程,从数据库中逆向生成模型,本想使用odbc连接的,但是需要安装驱动,mysql的还好弄,oracle对我来讲实在是有些麻烦,看到能用jdbc连接,就想试试, ...
- WPF Build Action
None: The file is not included in the project output group and is not compiled in the build process. ...
- Wolf RPG Editor游戏解包
前言 使用arc_conv_r53进行解包 使用touhouSE进行解包 使用DXEXTRACT进行解包 前言 Wolf RPG Editor由于其需要翻来覆去的转码,脚本名称等问题算是解包跟汉化中比 ...
- VS2013设置release版本可调试
http://blog.csdn.net/caoshangpa/article/details/76575640
- VC6下 try catch 在release下的杯具(默认情况下,要加上throw语句catch才不会被优化掉)
IDE:VC6 今天遇到一个小问题,把我郁闷了好久,××医生的VulEngine不时在wcsstr处发生crash,加了一番强大的参数检查后,再加上了强大的try catch,其实不是很喜欢用try和 ...
- 台电P89s mini root教程
根据论坛内的一些内容再结合自己的使用心得整理如下,本人双11购入P89s mini root成功 自带软件什么的都不见了 以下是个人root过程,有不一样的地方欢迎交流,说实话我也不是很懂 1.升级 ...