本文主要是python方面各类ocr的api对比问题,至于app推荐几款:合合信息(扫面全能王),TextGrabber,白描等等等等
工作需要,搞文字识别技术,对比了几家
百度的OCR:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue Jun 12 09:37:38 2018 利用百度api实现图片文本识别 @author: XnCSD """ import glob from os import path import os from aip import AipOcr from PIL import Image def convertimg(picfile, outdir): ''' 调整图片大小,对于过大的图片进行压缩 picfile: 图片路径 outdir: 图片输出路径 ''' img = Image.open(picfile) width, height = img.size while (width * height > 4000000): # 该数值压缩后的图片大约 两百多k width = width // 2 height = height // 2 new_img = img.resize((width, height), Image.BILINEAR) new_img.save(path.join(outdir, os.path.basename(picfile))) def baiduOCR(picfile, outfile): """利用百度api识别文本,并保存提取的文字 picfile: 图片文件名 outfile: 输出文件 """ filename = path.basename(picfile) APP_ID = '你自己的appid' # 刚才获取的 ID,下同 API_KEY = '创建完实例人家给' SECRECT_KEY = '创建完实例人家给' client = AipOcr(APP_ID, API_KEY, SECRECT_KEY) i = open(picfile, 'rb') img = i.read() print("正在识别图片:\t" + filename) # message = client.basicGeneral(img) # 通用文字识别,每天 50 000 次免费 message = client.basicAccurate(img) # 通用文字高精度识别,每天 800 次免费 print("识别成功!") i.close() with open(outfile, 'a+', encoding='utf8') as fo: fo.writelines("+" * 60 + '\n') fo.writelines("识别图片:\t" + filename + "\n" * 2) fo.writelines("文本内容:\n") # 输出文本内容 for text in message.get('words_result'): fo.writelines(text.get('words') + '\n') fo.writelines('\n' * 2) print("文本导出成功!") print() if __name__ == "__main__": outfile = '最后写入的文件名' outdir ='图片压缩后存储的路径' if path.exists(outfile): os.remove(outfile) if not path.exists(outdir): os.mkdir(outdir) print("压缩过大的图片...") # 首先对过大的图片进行压缩,以提高识别速度,将压缩的图片保存与临时文件夹中 for picfile in glob.glob("picture\*"): # 在picture文件夹里放图片 convertimg(picfile, outdir) print("图片识别...") for picfile in glob.glob("outdir\*"): baiduOCR(picfile, outfile) os.remove(picfile) print('图片文本提取结束!文本输出结果位于 %s 文件中。' % outfile) os.removedirs(outdir)
有道的OCR(加入了自己写的图片压缩以及循环的逻辑,如果有不对的地方请指出):
#/usr/bin/env python #coding=utf8 import hashlib from PIL import Image import os import requests import random import glob import json from os import path import base64 import time def convertimg(picfile, outdir): ''' 调整图片大小,对于过大的图片进行压缩 picfile: 图片路径 outdir: 图片输出路径 ''' img = Image.open(picfile) width, height = img.size while (width * height > 4000000): # 该数值压缩后的图片大约 两百多k width = width // 2 height = height // 2 new_img = img.resize((width, height), Image.BILINEAR) new_img.save(path.join(outdir, os.path.basename(picfile))) def youdaoOCR(picfile, outfile): """利用有道api识别文本,并保存提取的文字 picfile: 图片文件名 outfile: 输出文件 """ appKey = '自己的appkey' # 需要到有道云官网去注册实例 secretKey = '自己的secretKey' httpClient = None try: filename = path.basename(picfile) print('正在识别%s' % filename) # print(picfile) f = open(picfile, 'rb') # 二进制方式打开图文件 img = base64.b64encode(f.read()) # 读取文件内容,转换为base64编码 f.close() img = str(img, 'utf-8') detectType = '10012' imageType = '1' langType = 'auto' salt = random.randint(1, 65536) sign = appKey + img + str(salt) + secretKey m1 = hashlib.md5() m1.update(sign.encode('utf-8')) sign = m1.hexdigest() data = {'appKey': appKey, 'img': img, 'detectType': detectType, 'imageType': imageType, 'langType': langType, 'salt': str(salt), 'sign': sign} req = requests.post('http://openapi.youdao.com/ocrapi', data) content = req.text j = json.loads(content) # print(j) # print(j['Result']['regions']) lst = [] for regionstr in j['Result']['regions']: for lineStr in regionstr['lines']: # print(lineStr['text']) lst.append(lineStr['text']) result = ','.join(lst) print(result) except ValueError: print("error") if __name__ == '__main__': outfile = 'youdao.txt' # 最后写入的文件 outdir = '压缩的图片存储位置' if path.exists(outfile): os.remove(outfile) # 如果有要写入的文件,删除 if not path.exists(outdir): os.mkdir(outdir) # 如果存储压缩后的图片的文件夹,创建 print("正在压缩过大的图片....") for picfile in glob.glob(r"picture\*"): # 图片存储路径 convertimg(picfile, outdir) print('进行图片识别....') for picfile in glob.glob('压缩的图片存储位置\*'): youdaoOCR(picfile, outfile) os.remove(picfile) # print('图片提取结束!文本输出结果位于 %s 文件中。' % outfile) os.removedirs(outdir)
阿里的OCR(也加入了图片压缩以及循环功能(官网没有)):
import urllib.request import urllib.parse import json import time import base64 import glob import re from PIL import Image from os import path import os import time def convertimg(picfile, outdir): ''' 调整图片大小,对于过大的图片进行压缩 picfile: 图片路径 outdir: 图片输出路径 ''' img = Image.open(picfile) width, height = img.size while (width * height > 4000000): # 该数值压缩后的图片大约 两百多k width = width // 2 height = height // 2 new_img = img.resize((width, height), Image.BILINEAR) new_img.save(path.join(outdir, os.path.basename(picfile))) #请求头 headers = { 'Authorization': 'APPCODE 自己的appcode', # 阿里云官网上创建实例 'Content-Type': 'application/json; charset=UTF-8' } def posturl(url,data={}): # data为第一张的默认参数, data1为第二张的默认参数 try: params = json.dumps(dict).encode(encoding='UTF8') req = urllib.request.Request(url, params, headers) r = urllib.request.urlopen(req) html = r.read() r.close() return html.decode("utf8") except urllib.error.HTTPError as e: print(e.code) print(e.read().decode("utf8")) time.sleep(1) if __name__=="__main__": url_request = "https://ocrapi-document.taobao.com/ocrservice/document" outfile = 'ali.txt' outdir = '压缩图片的存储位置' if path.exists(outfile): os.remove(outfile) if not path.exists(outdir): os.mkdir(outdir) print('开始进行图片压缩....') for picfile in glob.glob(r"picture\*"): # 图片的存储位置 convertimg(picfile, outdir) print('开始进行图片识别....') for picfile in glob.glob("outdir\*"): filename = path.basename(picfile) print('正在识别%s' % filename) with open(picfile, 'rb') as f: # 以二进制读取本地图片 data = f.read() encodestr = str(base64.b64encode(data), 'utf-8') dict = {'img': encodestr} html = posturl(url_request, data=dict) os.remove(picfile) html1 = json.loads(html) # print(html) # print(type(html)) lst = [] # print(html1['prism_wordsInfo']) for i in html1['prism_wordsInfo']: if i.get('pos'): i.pop('pos') for k, v in i.items(): lst.append(v) # print(lst) str1 = ','.join(lst) print(str1) os.removedirs(outdir)
以下仅为个人意见:
我主要考虑的是有道和阿里:在准确度上差别不是很大,阿里稍微准确一丢丢
价格方面阿里是有道的两倍左右(阿里的为高精度文字识别)
速度上阿里更快一些。