hiroi-sora / Umi-OCR_v2

结束和新的开始
MIT License
935 stars 74 forks source link

服务调用方式 #31

Closed wandubuqin closed 11 months ago

wandubuqin commented 1 year ago

大佬,想咨询一下封装成服务形式的思路呢

hiroi-sora commented 1 year ago

你是指将 Umi-OCR 封装成一个服务?见 #28

还是想问 Umi 本身如何封装和调用OCR引擎的思路?

wandubuqin commented 1 year ago

Umi 本身如何封装和调用OCR引擎的思路,因为目前遇到的问题,需要使用者在前端页面截取图片并且把内容提交到后台,截图功能已经实现,想向您请教封装和掉用OCR的方式。

hiroi-sora commented 1 year ago

这是我在过去一年多对Umi的开发维护中总结出的一套OCR服务机制。特点是即使OCR接口本身不支持并发,这套机制也支持并发调用。

它分为两个部分:

1. 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

2. OCR服务管理器(单例)

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 的具体代码。

希望对你有帮助。

hiroi-sora commented 1 year ago

然后关于如何用python调用OCR的话,出门左转: https://github.com/hiroi-sora/PaddleOCR-json