Задокументируйте попытку разработки программы OCR

искусственный интеллект

В последнее время моя работа связана с проверкой некоторых документов и бумажных документов, поэтому я хочу сфотографировать бумажные документы и использовать слова для проверки друг друга. Раньше я думал о вызове интерфейса Youdao Zhiyun для перевода документов. Глядя на интерфейс API распознавания текста OCR, Youdao предоставляет множество различных интерфейсов для распознавания текста, включая рукописный ввод, печать, формы, распознавание всего вопроса, распознавание чеков, удостоверений личности, визитных карточек и т. д. Просто продолжайте использовать интерфейс Youdao Zhiyun, чтобы сделать небольшойdemo, чтобы попробовать все эти функции в качестве практики и в качестве подготовки к функциям, которые могут использоваться в будущем.

Подготовка к вызову интерфейса API

В первую очередь необходимо создать инстанс, создать приложение, привязать приложение и инстанс на личной странице Youdao Zhiyun и получить id и ключ приложения. Подробную информацию о процессе личной регистрации и создании приложения см. в статьеПоделитесь процессом разработки пакетного перевода файлов

Подробности процесса разработки

Ниже описан конкретный процесс разработки кода:

Эта демонстрация разработана с использованием python3, включая три файла maindow.py, ocrprocesser.py и ocrtools.py. В интерфейсной части для упрощения процесса разработки используется библиотека tkinter, идущая в комплекте с python, для обеспечения функции выбора распознаваемого файла и типа распознавания, отображения результата распознавания, ocrprocesser.py вызывает соответствующий интерфейс API в соответствии с выбранным типом для завершения процесса распознавания и возврата результата; ocrtools.py инкапсулирует различные API Youdao ocr после сортировки и реализует классифицированные вызовы.

  1. Интерфейсная часть:

    Код интерфейсной части выглядит следующим образом, используя сетку tkinter для расположения элементов.

    root=tk.Tk()
    root.title("netease youdao ocr test")
    frm = tk.Frame(root)
    frm.grid(padx='50', pady='50')
    ​
    btn_get_file = tk.Button(frm, text='选择待识别图片', command=get_files)
    btn_get_file.grid(row=0, column=0,  padx='10', pady='20')
    text1 = tk.Text(frm, width='40', height='5')
    text1.grid(row=0, column=1)
    ​
    combox=ttk.Combobox(frm,textvariable=tk.StringVar(),width=38)
    combox["value"]=img_type_dict
    combox.current(0)
    combox.bind("<<ComboboxSelected>>",get_img_type)
    combox.grid(row=1,column=1)
    ​
    label=tk.Label(frm,text="识别结果:")
    label.grid(row=2,column=0)
    text_result=tk.Text(frm,width='40',height='10')
    text_result.grid(row=2,column=1)
    ​
    btn_sure=tk.Button(frm,text="开始识别",command=ocr_files)
    btn_sure.grid(row=3,column=1)
    btn_clean=tk.Button(frm,text="清空",command=clean_text)
    btn_clean.grid(row=3,column=2)
    ​
    root.mainloop()
    

Событие привязки ocr_files() для btn_sure передает путь к файлу и тип идентификации в ocrprocesser:

def ocr_files():
    if ocr_model.img_paths:
        ocr_result=ocr_model.ocr_files()
        text_result.insert(tk.END,ocr_result)
    else :
        tk.messagebox.showinfo("提示","无文件")

2. Основным методом в ocrprocesser является ocr_files(), который вызывает инкапсулированный API после того, как base64 обработает изображение.

def ocr_files(self):
    for img_path in self.img_paths:
        img_file_name=os.path.basename(img_path).split('.')[0]
        #print('==========='+img_file_name+'===========')
        f=open(img_path,'rb')
        img_code=base64.b64encode(f.read()).decode('utf-8')
        f.close()
        print(img_code)
        ocr_result= self.ocr_by_netease(img_code, self.img_type)
        print(ocr_result)
        return ocr_result

3. После того, как я прочитал и разобрал документы API Youdao, он примерно разделен на следующие четыре входа в API: распознавание рукописного ввода/печати, распознавание удостоверения личности/визитной карточки, распознавание форм и распознавание всего вопроса. интерфейс другой, и параметры запроса тоже разные.Не все одинаковые, поэтому демка сначала различается по типу распознавания:

# 0-hand write
# 1-print
# 2-ID card
# 3-name card
# 4-table
# 5-problem
def get_ocr_result(img_code,img_type):
    if img_type==0 or img_type==1:
        return ocr_common(img_code)
    elif img_type==2 or img_type==3 :
        return ocr_card(img_code,img_type)
    elif img_type==4:
        return ocr_table(img_code)
    elif img_type==5:
        return ocr_problem(img_code)
    else:
        return "error:undefined type!"

Затем организуйте поля, такие как данные, в соответствии с параметрами, требуемыми интерфейсом, и просто проанализируйте и обработайте возвращаемые значения разных интерфейсов и верните:

def ocr_common(img_code):
    YOUDAO_URL='https://openapi.youdao.com/ocrapi'
    data = {}
    data['detectType'] = '10012'
    data['imageType'] = '1'
    data['langType'] = 'auto'
    data['img'] =img_code
    data['docType'] = 'json'
    data=get_sign_and_salt(data,img_code)
    response=do_request(YOUDAO_URL,data)['regions']
    result=[]
    for r in response:
        for line in r['lines']:
            result.append(line['text'])
    return result
​
​
def ocr_card(img_code,img_type):
    YOUDAO_URL='https://openapi.youdao.com/ocr_structure'
    data={}
    if img_type==2:
        data['structureType'] = 'idcard'
    elif img_type==3:
        data['structureType'] = 'namecard'
    data['q'] = img_code
    data['docType'] = 'json'
    data=get_sign_and_salt(data,img_code)
    return do_request(YOUDAO_URL,data)
​
def ocr_table(img_code):
    YOUDAO_URL='https://openapi.youdao.com/ocr_table'
    data = {}
    data['type'] = '1'
    data['q'] = img_code
    data['docType'] = 'json'
    data=get_sign_and_salt(data,img_code)
    return do_request(YOUDAO_URL,data)
​
def ocr_problem(img_code):
    YOUDAO_URL='https://openapi.youdao.com/ocr_formula'
    data = {}
    data['detectType'] = '10011'
    data['imageType'] = '1'
    data['img'] = img_code
    data['docType'] = 'json'
    data=get_sign_and_salt(data,img_code)
    response=do_request(YOUDAO_URL,data)['regions']
    result = []
    for r in response:
        for line in r['lines']:
            for l in line:
                result.append(l['text'])
    return result

get_sign_and_salt() добавляет к данным необходимую подпись и другую информацию:

def get_sign_and_salt(data,img_code):
    data['signType'] = 'v3'
    curtime = str(int(time.time()))
    data['curtime'] = curtime
    salt = str(uuid.uuid1())
    signStr = APP_KEY + truncate(img_code) + salt + curtime + APP_SECRET
    sign = encrypt(signStr)
    data['appKey'] = APP_KEY
    data['salt'] = salt
    data['sign'] = sign
    return data

Показать результаты

Рукописные результаты показывают:

Печать (Программа Юань использовала код для идентификации):

Распознавание визитных карточек, здесь я нашел шаблон визитной карточки, который кажется точным:

ID-карта (также шаблон):

Распознавание формы (это супер длинный json, >_

Распознавание всего вопроса (также сделано распознавание по формуле, результат распознавания в формате json относительно длинный, и выглядит не так интуитивно понятно, поэтому здесь его выкладывать не буду):

Суммировать

В общем, функция интерфейса по-прежнему очень мощная, и поддерживаются все виды. То есть у инженера визуального алгоритма нет функции классификации, поэтому ему нужно вызывать подинтерфейс для каждого типа изображения отдельно, а интерфейсы вообще нельзя смешивать.Например, в процессе разработки я представил изображение визитной карточки в качестве удостоверения личности для API, и результат, возвращаемый "" Items not found!", немного хлопотно для разработчиков, которые вызывают API, конечно, это также в определенной степени повышает точность распознавания, и личное предположение также должно быть для удобства подинтерфейсной тарификации: P.

адрес проекта:GitHub.com/lemon Q H/WOR…

От: Программа Юань Дэнни