Closed wandubuqin closed 11 months ago
你是指将 Umi-OCR 封装成一个服务?见 #28
还是想问 Umi 本身如何封装和调用OCR引擎的思路?
Umi 本身如何封装和调用OCR引擎的思路,因为目前遇到的问题,需要使用者在前端页面截取图片并且把内容提交到后台,截图功能已经实现,想向您请教封装和掉用OCR的方式。
这是我在过去一年多对Umi的开发维护中总结出的一套OCR服务机制。特点是即使OCR接口本身不支持并发,这套机制也支持并发调用。
它分为两个部分:
class OCR接口:
# 全同步设计,无需考虑并发
def __init__(self, info):
# 初始化。传入全局属性,如插件路径或在线API KEY
# 此时不要做耗时长的检查
pass
def start(self, info):
# 启动OCR接口。传入局部属性,如识别语言。
# 此时可以进行检查,如路径是否存在、api余额是否充足。
pass
def run(self, path):
# 进行一次识别。传入路径或图片,返回识别结果。
pass
def stop(self, ):
# 停止OCR接口。此时可结束引擎子进程,释放资源。
pass
class OCR服务管理器:
# 异步设计,允许并发调用
def __init__(self):
self.ocr = None # 保存当前接口实例
self.missions = [] # 保存当前所有任务链
self.thread = None # 保存当前线程对象
def start(self, info):
# 应用新的OCR接口。传入全局属性。
if self.ocr:
self.ocr.stop() # 停止旧的接口实例
self.ocr = OCR接口(info) # 构造新的接口实例
def run(self, mission):
# 允许并发调用。传入一个任务链。示例:
''' missions = {
"info": 局部属性
"paths": ["路径1", "路径2"]
"callback": 回调函数的引用
} '''
self.missions.append(mission)
if not self.thread:
self.thread = 启动新线程(self._runThread)
def _runThread(self):
# 在子线程执行
while self.missions 非空:
mission = 从 self.missions 中弹出一个任务链
# 将该任务链的局部属性传给OCR接口
self.ocr.start( mission["info"] )
# 循环,执行此任务链中所有任务
paths = mission["paths"]
for p in paths:
res = self.ocr.run(p) # 调用接口
mission["callback"](res) # 调用回调函数
# self.missions中所有任务链执行完毕,关闭子线程
self.thread = None
OCR服务管理器单例 = OCR服务管理器()
import OCR服务管理器单例
paths1 = ["test1.png", "test2.png", "test3.png"]
paths2 = ["test4.png", "test5.png", "test6.png"]
def 回调函数1(res):
print("1 ", res)
def 回调函数2(res):
print("2 ", res)
missions1 = {
"info": "中文图片",
"paths": paths1,
"callback": 回调函数1,
}
missions2 = {
"info": "英文图片",
"paths": paths2,
"callback": 回调函数2,
}
OCR服务管理器单例.start(全局参数)
OCR服务管理器单例.run(missions1)
OCR服务管理器单例.run(missions2)
大体思路如上,当然具体实施还需要添加亿点点细节。你也可以参考 UmiOCR-data/py_src/mission 的具体代码。
希望对你有帮助。
然后关于如何用python调用OCR的话,出门左转: https://github.com/hiroi-sora/PaddleOCR-json
大佬,想咨询一下封装成服务形式的思路呢