# -*- coding: utf-8 -*-
# @Time : 2020/5/22 0022 17:02
# @Author : LF
# @FileName: sheet_points_total.py
# @Software: PyCharm

import requests
import base64
from urllib import parse, request
import cv2
import re

from PIL import Image
from segment.sheet_resolve.tools.brain_api import get_ocr_text_and_coordinate_in_google_format
from segment.sheet_resolve.analysis.sheet.ocr_key_words import key_words

try:
    import tr
except Exception:
    pass

OCR_ACCURACY = 'accurate'


# def ocr_login():
#     grant_type = 'client_credentials'
#     client_id = OCR_CLIENT_ID
#     client_secret = OCR_CLIENT_SECRET
#
#     textmod = {'grant_type': grant_type, 'client_id': client_id, 'client_secret': client_secret}
#     textmod = parse.urlencode(textmod)
#
#     # 输出内容:user=admin&password=admin
#     header_dict = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko'}
#     url = 'https://aip.baidubce.com/oauth/2.0/token'
#     req = request.Request(url='{}{}{}'.format(url, '?', textmod), headers=header_dict)
#     res = request.urlopen(req).read()
#     token = eval(res.decode(encoding='utf-8'))['access_token']
#     return token
# def opecv2base64(img):
#     image = cv2.imencode('.jpg', img)[1]
#     base64_data = str(base64.b64encode(image))[2:-1]
#     return base64_data
# def get_ocr_raw_result(img, ocr_accuracy=OCR_ACCURACY, language_type='CHN_ENG'):
#     textmod = {'access_token': access_token}
#     textmod = parse.urlencode(textmod)
#     url = '{}{}{}{}'.format(OCR_BOX_URL, ocr_accuracy, '?', textmod)
#     url_general = '{}{}{}{}'.format(OCR_BOX_URL, 'general', '?', textmod)
#
#     headers = {'Content-Type': 'application/x-www-form-urlencoded'}
#
#     image_type = 'base64'
#     group_id = 'group001'
#     user_id = 'usr001'
#
#     image = opecv2base64(img)
#
#     data = {
#         'image_type': image_type,
#         'group_id': group_id,
#         'user_id': user_id,
#         'image': image,
#         'detect_direction': 'true',
#         'recognize_granularity': 'small',
#         'language_type': language_type,
#         # 'vertexes_location': 'true',
#         # 'probability': 'true'
#     }
#
#     resp = requests.post(url, data=data, headers=headers).json()
#     if resp.get('error_msg'):
#         if 'internal error' in resp.get('error_msg'):
#             resp = requests.post(url_general, data=data, headers=headers).json()
#             if resp.get('error_msg'):
#                 raise Exception("ocr {}!".format(resp.get('error_msg')))
#         else:
#             raise Exception("ocr {}!".format(resp.get('error_msg')))
#
#     return resp
# def get_ocr_text_and_coordinate(img, ocr_accuracy=OCR_ACCURACY, language_type='CHN_ENG'):
#     textmod = {'access_token': access_token}
#     textmod = parse.urlencode(textmod)
#     url = '{}{}{}{}'.format(OCR_BOX_URL, ocr_accuracy, '?', textmod)
#     url_general = '{}{}{}{}'.format(OCR_BOX_URL, 'general', '?', textmod)
#
#     headers = {'Content-Type': 'application/x-www-form-urlencoded'}
#
#     image_type = 'base64'
#     group_id = 'group001'
#     user_id = 'usr001'
#
#     image = opecv2base64(img)
#
#     data = {
#         'image_type': image_type,
#         'group_id': group_id,
#         'user_id': user_id,
#         'image': image,
#         'detect_direction': 'true',
#         'recognize_granularity': 'small',
#         'language_type': language_type,
#         # 'vertexes_location': 'true',
#         # 'probability': 'true'
#     }
#
#     resp = requests.post(url, data=data, headers=headers).json()
#     if resp.get('error_msg'):
#         if 'internal error' in resp.get('error_msg'):
#             resp = requests.post(url_general, data=data, headers=headers).json()
#             if resp.get('error_msg'):
#                 raise Exception("ocr {}!".format(resp.get('error_msg')))
#         else:
#             raise Exception("ocr {}!".format(resp.get('error_msg')))
#
#     words_result = resp.get('words_result')
#     return words_result
# def get_ocr_text_and_coordinate_in_google_format(img, ocr_accuracy=OCR_ACCURACY, language_type='CHN_ENG'):
#     textmod = {'access_token': access_token}
#     textmod = parse.urlencode(textmod)
#     url = '{}{}{}{}'.format(OCR_BOX_URL, ocr_accuracy, '?', textmod)
#     url_general = '{}{}{}{}'.format(OCR_BOX_URL, 'general', '?', textmod)
#
#     headers = {'Content-Type': 'application/x-www-form-urlencoded'}
#
#     image_type = 'base64'
#     group_id = 'group001'
#     user_id = 'usr001'
#
#     image = opecv2base64(img)
#
#     data = {
#         'image_type': image_type,
#         'group_id': group_id,
#         'user_id': user_id,
#         'image': image,
#         'detect_direction': 'true',
#         'recognize_granularity': 'small',
#         'language_type': language_type,
#         # 'vertexes_location': 'true',
#         # 'probability': 'true'
#     }
#
#     resp = requests.post(url, data=data, headers=headers).json()
#     if resp.get('error_msg'):
#         if 'internal error' in resp.get('error_msg'):
#             resp = requests.post(url_general, data=data, headers=headers).json()
#             if resp.get('error_msg'):
#                 raise Exception("ocr {}!".format(resp.get('error_msg')))
#         else:
#             raise Exception("ocr {}!".format(resp.get('error_msg')))
#
#     words_result = resp.get('words_result')
#     dict_list = [item2.get('location') for item in words_result for item2 in item['chars']]
#     char_list = [item2.get('char') for item in words_result for item2 in item['chars']]
#     words = [item.get('words') for item in words_result]
#     matrix = []
#     for adict in dict_list:
#         xmin = adict['left']
#         ymin = adict['top']
#         xmax = adict['width'] + adict['left']
#         ymax = adict['top'] + adict['height']
#         item0 = (xmin, ymin, xmax, ymax)
#         matrix.append(item0)
#
#     res_dict = {'chars': char_list, 'coordinates': matrix, 'words': words}
#     return res_dict


def model_type_score(all_type_score_one, choice_box, cloze_box, solve_box,composition_box):  # 与模型得到边框与type_score对应
    '''
    :param all_type_score_one: 模型得到的单个type_score的坐标位置
    :param choice_box: 模型得到的选择题坐标位置
    :param cloze_box: 模型得到的填空题坐标位置
    :param solve_box: 模型得到的解答题坐标位置
    :return:
    '''

    N_choice = len(choice_box)
    N_cloze = len(cloze_box)
    N_solve_box = len(solve_box)
    N_composition = len(composition_box)
    min_choice_dict = {}
    min_cloze_dict = {}
    min_solve_dict = {}
    min_composition_dict = {}
    test_result1 = 0
    min_choice = 100000000
    min_cloze = 100000000
    min_solve = 100000000
    min_composition = 100000000

    for j in range(N_choice):
        choice_distance_x = abs(list(all_type_score_one)[0] - choice_box[j][0])
        choice_distance_y = abs(list(all_type_score_one)[1] - choice_box[j][1])
        choice_distance = choice_distance_x + choice_distance_y
        if choice_distance < min_choice:
            min_choice = choice_distance
            min_choice_dict = {'min_choice': min_choice,
                               'bounding_box': choice_box[j],
                               'label': 'choice',
                               'type_box': all_type_score_one}
    for k in range(N_cloze):
        cloze_distance_x = abs(list(all_type_score_one)[0] - cloze_box[k][0])
        cloze_distance_y = abs(list(all_type_score_one)[1] - cloze_box[k][1])
        cloze_distance = cloze_distance_x + cloze_distance_y
        if cloze_distance < min_cloze:
            min_cloze = cloze_distance
            min_cloze_dict = {'min_cloze': min_cloze,
                              'bounding_box': cloze_box[k],
                              'label': 'cloze',
                              'type_box': all_type_score_one}
    for l in range(N_solve_box):
        solve_distance_x = abs(list(all_type_score_one)[0] - solve_box[l][0])
        solve_distance_y = abs(list(all_type_score_one)[1] - solve_box[l][1])
        solve_distance = solve_distance_x + solve_distance_y
        if solve_distance < min_solve:
            min_solve = solve_distance
            min_solve_dict = {'min_solve': min_solve,
                              'bounding_box': solve_box[l],
                              'label': 'solve',
                              'type_box': all_type_score_one}
    for m in range(N_composition):
        composition_distance_x = abs(list(all_type_score_one)[0] - composition_box[m][0])
        composition_distance_y = abs(list(all_type_score_one)[1] - composition_box[m][1])
        composition_distance = composition_distance_x + composition_distance_y
        if composition_distance < min_composition:
            min_composition = composition_distance
            min_composition_dict = {'min_cloze': min_composition,
                              'bounding_box': composition_box[m],
                              'label': 'composition',
                              'type_box': all_type_score_one}

    if min_choice < min_cloze and min_choice < min_solve and min_choice < min_composition:
        # 建立相互关联的关系。 即表示该type_score对应于选择题
        if test_result1 < 400:
            test_result1 = min_choice_dict
        else:
            test_result1 = -1

    elif min_cloze < min_choice and min_cloze < min_solve and min_cloze < min_composition:
        # 建立相互关联的关系。 即表示该type_score对应于填空题
        if test_result1 < 400:
            test_result1 = min_cloze_dict
        else:
            test_result1 = -1

    elif min_solve < min_cloze and min_solve < min_choice and min_solve < min_composition:
        # 建立相互关联的关系。 即表示该type_score对应于解答题
        if test_result1 < 300:
            test_result1 = min_solve_dict
        else:
            test_result1 = -1
    elif min_composition < min_cloze and min_composition < min_choice and min_composition < min_solve:
        # 建立相互关联的关系。 即表示该type_score对应于解答题
        if test_result1 < 300:
            test_result1 = min_composition_dict
        else:
            test_result1 = -1

    return test_result1


def ocr_key_words(rect, type_score_dict):  # 将ocr识别得到的文字与模型得到的type_score对应
    '''
    :param rect: OCR识别结果数组，格式：res = {'chars': [},'coordinates': [(),()},'words': []}
    :param type_score_dict: 模型得到的type_score(与模型得到的边框相对应)
    :return: 字典中添加word
    '''
    len_ocr = len(rect['chars'])
    xmin = type_score_dict['type_box'][0]
    ymin = type_score_dict['type_box'][1]
    xmax = type_score_dict['type_box'][2]
    ymax = type_score_dict['type_box'][3]
    words = []
    for j in range(len_ocr):
        if rect['coordinates'][j][0] - xmin > -30 and rect['coordinates'][j][1] - ymin > -30 and rect['coordinates'][j][
            2] - xmax < 30 and rect['coordinates'][j][3] - ymax < 30:
            word = rect['chars'][j]
            words.append(word)
    type_score_dict['words'] = words
    type_score_dict_ocr = type_score_dict

    return type_score_dict_ocr





def get_sheet_number_total(answer_sheet, res, img0):

    # img0 = cv2.imread(img_path0)
    image_src = Image.fromarray(cv2.cvtColor(img0, cv2.COLOR_BGR2RGB))
    img_w, img_h = image_src.size
    if (image_src.mode == 'RGB'):
        image_src = image_src.convert("L")
    choice_boxs = []
    choice_m_boxs = []
    cloze_boxs = []
    solve_boxs = []
    type_score_boxs = []
    select_boxs = []
    all_test = []
    num_choice = 0
    num_choice_m = 0
    num_cloze = 0
    num_slove = 0
    num_select = 0
    num_type_score = 0
    volume_last = []
    Score_last = []
    score_last_one = 0
    volume_last_one = 0
    model_box2 = []
    composition_boxs = []
    score2 = []
    num_redundance = 0
    num_composition = 0
    j_temp = []
    jj_temp =[]

    for ele in answer_sheet["regions"]:  # 从模型输出获取对应标签的边框信息
        if ele["class_name"] == 'choice':
            choice_box = ele['bounding_box']
            choice_one = (
                int(choice_box['xmin']), int(choice_box['ymin']), int(choice_box['xmax']), int(choice_box['ymax']))
            choice_boxs.append(choice_one)
            num_choice = num_choice + 1
        elif ele["class_name"] == 'choice_m':
            choice_m_boxs.append(ele['bounding_box'])
            num_choice_m = num_choice_m + 1
        elif ele["class_name"] == 'cloze':
            cloze_box = ele['bounding_box']
            cloze_one = (int(cloze_box['xmin']), int(cloze_box['ymin']), int(cloze_box['xmax']), int(cloze_box['ymax']))
            cloze_boxs.append(cloze_one)
            num_cloze = num_cloze + 1
        elif ele["class_name"] == 'composition0' or ele["class_name"] == 'composition' or ele[
            "class_name"] == 'correction':
            composition_box = ele['bounding_box']
            composition_one = (int(composition_box['xmin']), int(composition_box['ymin']), int(composition_box['xmax']),
                               int(composition_box['ymax']))
            composition_boxs.append(composition_one)
            num_composition = num_composition + 1
        elif ele["class_name"] == 'solve' or ele["class_name"] == 'solve0':
            solve_box = ele['bounding_box']
            solve_one = (int(solve_box['xmin']), int(solve_box['ymin']), int(solve_box['xmax']), int(solve_box['ymax']))
            solve_boxs.append(solve_one)
            num_slove = num_slove + 1
        elif ele["class_name"] == 'select_s' or ele["class_name"] == 'select_b':
            select_box = ele['bounding_box']
            select_one = (
                int(select_box['xmin']), int(select_box['ymin']), int(select_box['xmax']), int(select_box['ymax']))
            select_boxs.append(select_one)
            num_select = num_select + 1
        elif ele["class_name"] == 'type_score':
            type_score_box = ele['bounding_box']
            type_score_one = (int(type_score_box['xmin']), int(type_score_box['ymin']), int(type_score_box['xmax']),
                              int(type_score_box['ymax']))
            type_score_boxs.append(type_score_one)
            num_type_score = num_type_score + 1

    '''解析type_score与对应分割模块的分数'''
    for i in range(len(type_score_boxs)):
        type_score_flag = 1
        test_result1 = model_type_score(type_score_boxs[i], choice_boxs, cloze_boxs, solve_boxs, composition_boxs)
        if test_result1 != -1 and test_result1 != 0:
            if type_score_boxs[i][0] - 5 > 0:
                xminss = type_score_boxs[i][0]-5
            else:
                xminss = type_score_boxs[i][0]
            if type_score_boxs[i][1] - 5 > 0:
                yminss = type_score_boxs[i][1] - 5
            else:
                yminss = type_score_boxs[i][1]
            if type_score_boxs[i][2] + 5 < img_w:
                xmaxss = type_score_boxs[i][2] + 5
            else:
                xmaxss = type_score_boxs[i][2]
            if type_score_boxs[i][3] + 5 < img_h:
                ymaxss = type_score_boxs[i][3] + 5
            else:
                ymaxss = type_score_boxs[i][3]
            test_result1['words'] = str()
            try:  # tr_OCR
                print('tr_OCR')
                image_src_type_score = image_src.crop((xminss, yminss, xmaxss, ymaxss))
                type_score_dict_ocr = tr.run(image_src_type_score)
                for t in range(len(type_score_dict_ocr)):
                    test_result1['words'] = test_result1['words'] + type_score_dict_ocr[t][1]
            except Exception as e:  # baidu_OCR
                print('baidu_OCR')
                type_score_dict_ocr = get_ocr_text_and_coordinate_in_google_format(img0[yminss:ymaxss, xminss:xmaxss], ocr_accuracy=OCR_ACCURACY,language_type='CHN_ENG')
                for t in range(len(type_score_dict_ocr['words'])):
                    test_result1['words'] = test_result1['words'] + type_score_dict_ocr['words'][t]

            test = key_words(test_result1, type_score_flag)
            if test == {}:
                ### 添加返回值OCR结果
                add_ocr = {}
                add_ocr['model_box'] = test_result1['bounding_box']
                add_ocr['label'] = test_result1['label']
                add_ocr['number'] = -1
                add_ocr['score'] = -1
                add_ocr['number_score'] = -1
                add_ocr['counts'] = -1
                add_ocr['ocr'] = test_result1['words']
                Score_last.append(add_ocr)
            elif test['volume_structure'] == -1 and test['Score_structure'] == -1:
                ### 添加返回值OCR结果
                add_ocr = {}
                add_ocr['model_box'] = test_result1['bounding_box']
                add_ocr['label'] = test_result1['label']
                add_ocr['number'] = -1
                add_ocr['score'] = -1
                add_ocr['number_score'] = -1
                add_ocr['counts'] = -1
                add_ocr['ocr'] = test_result1['words']
                Score_last.append(add_ocr)
            elif test != {}:
                if test['volume_structure'] != -1 and int(
                        test['volume_structure'][0]['volume_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    test['volume_structure'][0]['volume_total_score'] = int(
                        test['volume_structure'][0]['volume_total_score']) % 100
                elif test['volume_structure'] == -1 and test['Score_structure'] != -1 and int(
                        test['Score_structure'][0]['item_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    test['Score_structure'][0]['item_total_score'] = int(
                        test['Score_structure'][0]['item_total_score']) % 100
                all_test.append(test)

    ''' 解析模型分割模块没有对应的type_score时的分数'''
    for jjjj in range(len(all_test)):
        if all_test[jjjj]['Score_structure'] != -1:
            label_1 = all_test[jjjj]['Score_structure'][0]['label']
            if label_1 == 'choice':
                if choice_boxs.count(all_test[jjjj]['Score_structure'][0]['bounding_box']):
                    choice_boxs.remove(all_test[jjjj]['Score_structure'][0]['bounding_box'])
            elif label_1 == 'cloze':
                if cloze_boxs.count(all_test[jjjj]['Score_structure'][0]['bounding_box']):
                    cloze_boxs.remove(all_test[jjjj]['Score_structure'][0]['bounding_box'])
            elif label_1 == 'solve':
                if solve_boxs.count(all_test[jjjj]['Score_structure'][0]['bounding_box']):
                    solve_boxs.remove(all_test[jjjj]['Score_structure'][0]['bounding_box'])
            elif label_1 == 'composition':
                if solve_boxs.count(all_test[jjjj]['Score_structure'][0]['bounding_box']):
                    solve_boxs.remove(all_test[jjjj]['Score_structure'][0]['bounding_box'])
    if choice_boxs != []:  # 9月16号修改
        type_score_flag = 0
        for ij in range(len(choice_boxs)):
            if choice_boxs[ij][1] - 150 > 0:
                yminss = choice_boxs[ij][1] - 150
            else:
                yminss = choice_boxs[ij][1]
            if choice_boxs[ij][0] - 100 > 0:
                xminss = choice_boxs[ij][0] - 100
            else:
                xminss = choice_boxs[ij][0]
            if yminss + 200 < img_h:
                ymaxss = yminss + 200
            else:
                ymaxss = choice_boxs[ij][3]
            type_score_dict_ocrs = {}
            new_test = {}

            try:  # tr_OCR
                print('tr_OCR')
                image_choice = image_src.crop((xminss, yminss, choice_boxs[ij][2], ymaxss))
                res1 = tr.run(image_choice)
                for i in range(len(res1)):
                    if res1[i][1].find('分') != -1:
                        type_score_dict_ocrs['words'] = res1[i][1]
                    else:
                        continue
            except Exception as e:  # baidu_OCR
                print('baidu_OCR')
                res1 = get_ocr_text_and_coordinate_in_google_format(img0[yminss:ymaxss, xminss:choice_boxs[ij][2]], ocr_accuracy=OCR_ACCURACY,language_type='CHN_ENG')
                for i in range(len(res1['words'])):
                    if res1['words'][i].find('分') != -1:
                        type_score_dict_ocrs['words'] = res1['words'][i]
                    else:
                        continue
            if type_score_dict_ocrs != {}:
                new_test = key_words(type_score_dict_ocrs, type_score_flag)
            if new_test != {} and new_test['volume_structure'] != -1 and (
                    int(new_test['volume_structure'][0]['volume_total_score']) > 4 or int(
                    new_test['volume_structure'][0]['volume_score']) > 4):  # 如果识别到分数，添加到输出信息；如果还没有识别到分数，默认没有分数
                if int(new_test['volume_structure'][0]['volume_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    new_test['volume_structure'][0]['volume_total_score'] = int(
                        new_test['volume_structure'][0]['volume_total_score']) % 100
                new_test['volume_structure'][0]['bounding_box'] = choice_boxs[ij]
                new_test['volume_structure'][0]['label'] = 'choice'
                all_test.append(new_test)
            elif new_test != {} and new_test['volume_structure'] == -1 and new_test['Score_structure'] != -1 and (
                    int(new_test['Score_structure'][0]['item_total_score']) > 4 or int(
                    new_test['Score_structure'][0]['item_score']) > 4):  # 如果识别到分数，添加到输出信息；如果还没有识别到分数，默认没有分数
                if int(new_test['Score_structure'][0]['item_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    new_test['Score_structure'][0]['item_total_score'] = int(
                        new_test['Score_structure'][0]['item_total_score']) % 100
                new_test['Score_structure'][0]['bounding_box'] = choice_boxs[ij]
                new_test['Score_structure'][0]['label'] = 'choice'
                all_test.append(new_test)
    if cloze_boxs != []:
        type_score_flag = 0
        for ij in range(len(cloze_boxs)):
            if cloze_boxs[ij][1] - 100 > 0:
                yminss = cloze_boxs[ij][1] - 100
            else:
                yminss = cloze_boxs[ij][1]
            if cloze_boxs[ij][0] - 100 > 0:
                xminss = cloze_boxs[ij][0] - 100
            else:
                xminss = cloze_boxs[ij][0]
            type_score_dict_ocrs = {}
            new_test = {}

            try:  # tr_OCR
                print('tr_OCR')
                image_choice = image_src.crop((xminss, yminss, cloze_boxs[ij][2], cloze_boxs[ij][3]))
                res1 = tr.run(image_choice)
                for i in range(len(res1)):
                    if res1[i][1].find('分') != -1:
                        type_score_dict_ocrs['words'] = res1[i][1]
                    else:
                        continue
            except Exception as e:  # baidu_OCR
                print('baidu_OCR')
                res1 = get_ocr_text_and_coordinate_in_google_format(
                    img0[yminss:cloze_boxs[ij][3], xminss:cloze_boxs[ij][2]], ocr_accuracy=OCR_ACCURACY,
                    language_type='CHN_ENG')
                for i in range(len(res1['words'])):
                    if res1['words'][i].find('分') != -1:
                        type_score_dict_ocrs['words'] = res1['words'][i]
                    else:
                        continue
            if type_score_dict_ocrs != {}:
                new_test = key_words(type_score_dict_ocrs, type_score_flag)
            if new_test != {} and new_test['volume_structure'] != -1 and (int(new_test['volume_structure'][0]['volume_total_score']) > 4 or int(new_test['volume_structure'][0]['volume_score']) > 4):  # 如果识别到分数，添加到输出信息；如果还没有识别到分数，默认没有分数
                if int(new_test['volume_structure'][0]['volume_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    new_test['volume_structure'][0]['volume_total_score'] = int(
                        new_test['volume_structure'][0]['volume_total_score']) % 100
                new_test['volume_structure'][0]['bounding_box'] = cloze_boxs[ij]
                new_test['volume_structure'][0]['label'] = 'cloze'
                all_test.append(new_test)
            elif new_test != {} and new_test['volume_structure'] == -1 and new_test['Score_structure'] != -1 and (int(new_test['Score_structure'][0]['item_total_score']) > 4 or int(new_test['Score_structure'][0]['item_score']) > 4):  # 如果识别到分数，添加到输出信息；如果还没有识别到分数，默认没有分数
                if int(new_test['Score_structure'][0]['item_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    new_test['Score_structure'][0]['item_total_score'] = int(
                        new_test['Score_structure'][0]['item_total_score']) % 100
                new_test['Score_structure'][0]['bounding_box'] = cloze_boxs[ij]
                new_test['Score_structure'][0]['label'] = 'cloze'
                all_test.append(new_test)
    if solve_boxs != []:
        type_score_flag = 0
        for ij in range(len(solve_boxs)):
            xminss = solve_boxs[ij][0]
            yminss = solve_boxs[ij][1]
            if solve_boxs[ij][2] - xminss > 1000:
                xmaxss = xminss + 1000
            else:
                xmaxss = solve_boxs[ij][2]
            if yminss + 500 > img_h:
                ymaxss = yminss + 500
            else:
                ymaxss = solve_boxs[ij][3]
            type_score_dict_ocrs = {}
            new_test = {}

            try:  # tr_OCR
                print('tr_OCR')
                image_choice = image_src.crop((xminss, yminss, xmaxss, ymaxss))
                res1 = tr.run(image_choice)
                for i in range(len(res1)):
                    if res1[i][1].find('分') != -1:
                        type_score_dict_ocrs['words'] = res1[i][1]
                    elif i == len(res1)-1:
                        for ii in range(len(res1)):
                            if res1[ii][1].find('题') != -1 or res1[ii][1].find('.') != -1 or res1[ii][1].find('、') != -1:
                                type_score_dict_ocrs['words'] = res1[ii][1]
                            else:
                                continue
                    else:
                        continue
            except Exception as e:  # baidu_OCR
                print('baidu_OCR')
                res1 = get_ocr_text_and_coordinate_in_google_format(
                    img0[yminss:ymaxss, xminss:xmaxss], ocr_accuracy=OCR_ACCURACY,
                    language_type='CHN_ENG')
                for i in range(len(res1['words'])):
                    if res1['words'][i].find('分') != -1:
                        type_score_dict_ocrs['words'] = res1['words'][i]
                    elif i == len(res1['words'])-1:
                        for ii in range(len(res1['words'])):
                            if res1['words'][ii].find('题') != -1 or res1['words'][ii][1].find('.') != -1 or res1['words'][ii].find('、') != -1:
                                type_score_dict_ocrs['words'] = res1['words'][ii]
                            else:
                                continue
                    else:
                        continue
            if type_score_dict_ocrs != {}:
                new_test = key_words(type_score_dict_ocrs, type_score_flag)
            if new_test != {} and new_test['volume_structure'] != -1 and int(new_test['volume_structure'][0][
                                                                                 'volume_total_score']) > 5:  # 如果识别到分数，添加到输出信息；如果还没有识别到分数，默认没有分数
                if int(new_test['volume_structure'][0][
                           'volume_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    new_test['volume_structure'][0]['volume_total_score'] = int(
                        new_test['volume_structure'][0]['volume_total_score']) % 100
                new_test['volume_structure'][0]['bounding_box'] = solve_boxs[ij]
                new_test['volume_structure'][0]['label'] = 'solve'
                all_test.append(new_test)
            elif new_test != {} and new_test['volume_structure'] == -1 and new_test[
                'Score_structure'] != -1 and (
                    int(new_test['Score_structure'][0]['item_total_score']) > 5 or int(
                    new_test['Score_structure'][0][
                        'item_total_score']) == -1):  # 如果识别到分数，添加到输出信息；如果还没有识别到分数，默认没有分数
                if int(new_test['Score_structure'][0]['item_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    new_test['Score_structure'][0]['item_total_score'] = int(
                        new_test['Score_structure'][0]['item_total_score']) % 100
                new_test['Score_structure'][0]['bounding_box'] = solve_boxs[ij]
                new_test['Score_structure'][0]['label'] = 'solve'
                all_test.append(new_test)
    if composition_boxs != []:
        type_score_flag = 0
        for ij in range(len(composition_boxs)):
            if composition_boxs[ij][1] - 250 > 0:
                yminss = composition_boxs[ij][1] - 250
            else:
                yminss = composition_boxs[ij][1]
            if composition_boxs[ij][0] - 100 > 0:
                xminss = composition_boxs[ij][0] - 100
            else:
                xminss = composition_boxs[ij][0]
            type_score_dict_ocrs = {}

            try:  # tr_OCR
                print('tr_OCR')
                image_choice = image_src.crop((xminss, yminss, composition_boxs[ij][2], composition_boxs[ij][3]))
                res1 = tr.run(image_choice)
                for i in range(len(res1)):
                    if res1[i][1].find('分') != -1:
                        type_score_dict_ocrs['words'] = res1[i][1]
                    elif i == len(res1):
                        for ii in range(len(res1)):
                            if res1[i][1].find('题') != -1 or res1[i][1].find('.') != -1 or res1[i][1].find('、') != -1:
                                type_score_dict_ocrs['words'] = res1[i][1]
                            else:
                                continue
            except Exception as e:  # baidu_OCR
                print('baidu_OCR')
                res1 = get_ocr_text_and_coordinate_in_google_format(
                    img0[yminss:composition_boxs[ij][3], xminss:composition_boxs[ij][2]], ocr_accuracy=OCR_ACCURACY,
                    language_type='CHN_ENG')
                for i in range(len(res1['words'])):
                    if res1['words'][i].find('分') != -1:
                        type_score_dict_ocrs['words'] = res1['words'][i]
                    elif i == len(res1):
                        for ii in range(len(res1['words'])):
                            if res1['words'][i].find('题') != -1 or res1['words'][i][1].find('.') != -1 or res1['words'][
                                i].find('、') != -1:
                                type_score_dict_ocrs['words'] = res1['words'][i]
                            else:
                                continue
            if type_score_dict_ocrs != {}:
                new_test = key_words(type_score_dict_ocrs, type_score_flag)
            if new_test != {} and new_test['volume_structure'] != -1 and int(
                    new_test['volume_structure'][0]['volume_total_score']) > 4:  # 如果识别到分数，添加到输出信息；如果还没有识别到分数，默认没有分数
                if int(new_test['volume_structure'][0]['volume_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    new_test['volume_structure'][0]['volume_total_score'] = int(
                        new_test['volume_structure'][0]['volume_total_score']) % 100
                new_test['volume_structure'][0]['bounding_box'] = composition_boxs[ij]
                new_test['volume_structure'][0]['label'] = 'composition'
                all_test.append(new_test)
            elif new_test != {} and new_test['volume_structure'] == -1 and new_test[
                'Score_structure'] != -1 and int(
                new_test['Score_structure'][0]['item_total_score']) > 4:  # 如果识别到分数，添加到输出信息；如果还没有识别到分数，默认没有分数
                if int(new_test['Score_structure'][0]['item_total_score']) > 200:  # 暂定试卷分数都在200以内，超过200的表示识别错误
                    new_test['Score_structure'][0]['item_total_score'] = int(
                        new_test['Score_structure'][0]['item_total_score']) % 100
                new_test['Score_structure'][0]['bounding_box'] = composition_boxs[ij]
                new_test['Score_structure'][0]['label'] = 'composition'
                all_test.append(new_test)
    for aaa in range(len(all_test)):
        if all_test[aaa]['Score_structure'] != -1 and all_test[aaa]['volume_structure'] == -1:
            score_last_one = {'model_box': dict(all_test[aaa])['Score_structure'][0]['bounding_box'],
                              'label': dict(all_test[aaa])['Score_structure'][0]['label'],
                              'number': dict(all_test[aaa])['Score_structure'][0]['item_N'],
                              'score': dict(all_test[aaa])['Score_structure'][0]['item_total_score'],
                              'number_score': dict(all_test[aaa])['Score_structure'][0]['item_score'],
                              'counts': dict(all_test[aaa])['Score_structure'][0]['item_count']}
            Score_last.append(score_last_one)
            continue
        elif all_test[aaa]['Score_structure'] != -1 and all_test[aaa]['volume_structure'] != -1:
            score_last_one = {'model_box': dict(all_test[aaa])['Score_structure'][0]['bounding_box'],
                              'label': dict(all_test[aaa])['Score_structure'][0]['label'],
                              'number': -1,
                              'score': dict(all_test[aaa])['Score_structure'][0]['volume_total_score'],
                              'number_score': dict(all_test[aaa])['Score_structure'][0]['volume_score'],
                              'counts': dict(all_test[aaa])['Score_structure'][0]['volume_count']}
            Score_last.append(score_last_one)

            volume_last_one = {'volume_N': dict(all_test[aaa])['volume_structure'][0]['volume_N'],
                               'volume_total_score': dict(all_test[aaa])['volume_structure'][0]['volume_total_score'],
                               'volume_count': dict(all_test[aaa])['volume_structure'][0]['volume_count'],
                               'volume_score': dict(all_test[aaa])['volume_structure'][0]['volume_score'],
                               'keyword_type': dict(all_test[aaa])['volume_structure'][0]['keyword_type']}
            volume_last.append(volume_last_one)
            continue
        elif all_test[aaa]['volume_structure'] != -1:
            volume_last_one = {'volume_N': dict(all_test[aaa])['volume_structure'][0]['volume_N'],
                               'volume_total_score': dict(all_test[aaa])['volume_structure'][0]['volume_total_score'],
                               'volume_count': dict(all_test[aaa])['volume_structure'][0]['volume_count'],
                               'volume_score': dict(all_test[aaa])['volume_structure'][0]['volume_score'],
                               'keyword_type': dict(all_test[aaa])['volume_structure'][0]['keyword_type']}
            volume_last.append(volume_last_one)
            continue
    # Score_last = sorted(Score_last, key=lambda x: (
    # x['model_box'][0], x['model_box'][0] + x['model_box'][1], -x['score']))  # 按答题卡顺序输出

    '''去重一个边框可能对应多个type_score的情况,英语单独解析'''
    len_Score_last = len(Score_last)
    if answer_sheet['subject'] == 'english':
        for i in range(len_Score_last):
            if Score_last[i]['label'] == 'cloze':
                if Score_last[i]['model_box'] in model_box2:
                    index2 = model_box2.index(Score_last[i]['model_box'])
                    score = Score_last[i]['score']
                    if score < score2[index2] and score2[index2] < 20:  # 去重，type_score多余的包含小题分数
                        Score_last[i] = -1
                    elif score < score2[index2] and score2[index2] > 20:  # 去重，type_score多余的包含分卷分数
                        Score_last[index2] = -1
                    elif score > score2[index2] and score < 20:  # 去重，type_score在不大于30分的情况下，暂定保留更大的分数
                        Score_last[index2] = -1
                    elif score > score2[index2] and score > 20:  # 去重，type_score去除大于30分的重复分数
                        Score_last[i] = -1
                    else:
                        Score_last[i] = -1
                else:
                    model_box2.append(Score_last[i]['model_box'])
                    score2.append(Score_last[i]['score'])
            else:
                if Score_last[i]['model_box'] in model_box2:
                    index2 = model_box2.index(Score_last[i]['model_box'])
                    score = Score_last[i]['score']
                    if score < score2[index2]:  # 去重，type_score多余的包含小题分数
                        Score_last[i] = -1
                    elif score > score2[index2]:  # 去重，type_score在不大于30分的情况下，暂定保留更大的分数
                        Score_last[index2] = -1
                    else:
                        Score_last[i] = -1
                else:
                    model_box2.append(Score_last[i]['model_box'])
                    score2.append(Score_last[i]['score'])
    else:
        for i in range(len_Score_last):
            if Score_last[i]['model_box'] in model_box2:
                index2 = model_box2.index(Score_last[i]['model_box'])
                score = Score_last[i]['score']
                if score < score2[index2] and score2[index2] < 30:  # 去重，type_score多余的包含小题分数
                    Score_last[i] = -1
                elif score < score2[index2] and score2[index2] > 30:  # 去重，type_score多余的包含分卷分数
                    Score_last[index2] = -1
                elif score > score2[index2] and score < 30:  # 去重，type_score在不大于30分的情况下，暂定保留更大的分数
                    Score_last[index2] = -1
                elif score > score2[index2] and score > 30:  # 去重，type_score去除大于30分的重复分数
                    Score_last[i] = -1
                else:
                    Score_last[i] = -1
            else:
                model_box2.append(Score_last[i]['model_box'])
                score2.append(Score_last[i]['score'])
    while num_redundance < len_Score_last:  # 去重一个边框可能对应多个type_score的情况
        if Score_last[num_redundance] == -1:
            del Score_last[num_redundance]
            len_Score_last = len_Score_last - 1
        else:
            num_redundance = num_redundance + 1
    # print(Score_last)
    # print(volume_last)  # 分卷信息，暂不输出
    # print(answer_sheet['regions'])

    if Score_last != []:
        for i in range(len(Score_last)): # 多选题题号和分数逐个显示
            if type(Score_last[i]['number']) is list:
                C_q_s = len(Score_last[i]['number']) * [Score_last[i]['score']]
                Score_last[i]['score'] = C_q_s

        '''choice_m/cloze_s分数解析'''
        if num_choice == 1 or num_cloze == 1:  # 对应choice_m分数
            for i in range(len(Score_last)):
                if Score_last[i]['label'] == 'choice':
                    count_choice_m = 0
                    for j in range(len(answer_sheet['regions'])):
                        if answer_sheet['regions'][j]['class_name'] == 'choice_m':
                            if Score_last[i]['number_score'] != -1 and ('number' in answer_sheet['regions'][j].keys()):
                                answer_sheet['regions'][j]['default_points'] = len(answer_sheet['regions'][j]['number']) * [float(Score_last[i]['number_score'])]
                            elif Score_last[i]['number_score'] == -1 and Score_last[i]['score'] != -1 and 'number' in answer_sheet['regions'][j].keys():
                                count_choice_m = count_choice_m + len(answer_sheet['regions'][j]['number'])
                                j_temp.append(j)
                        if j == len(answer_sheet['regions']) - 1 and j_temp !=[]:
                            for index, jj in enumerate(j_temp):
                                num_score_m = round(float(Score_last[i]['score'] / count_choice_m),1)
                                answer_sheet['regions'][jj]['default_points'] = len(answer_sheet['regions'][jj]['number']) * [num_score_m]
                            break

                elif Score_last[i]['label'] == 'cloze':
                    count_cloze_s = 0
                    for j in range(len(answer_sheet['regions'])):
                        if answer_sheet['regions'][j]['class_name'] == 'cloze_s':
                            if Score_last[i]['number_score'] != -1:
                                answer_sheet['regions'][j]['default_points'] = Score_last[i]['number_score']
        elif num_choice > 1 or num_cloze >1:
            for i in range(len(Score_last)):
                if Score_last[i]['label'] == 'choice':
                    count_choice_m = 0
                    for j in range(len(answer_sheet['regions'])):
                        if answer_sheet['regions'][j]['class_name'] == 'choice_m':
                            xmin_dis = answer_sheet['regions'][j]['bounding_box']['xmin'] - \
                                       Score_last[i]['model_box'][0]
                            ymin_dis = answer_sheet['regions'][j]['bounding_box']['ymin'] - \
                                       Score_last[i]['model_box'][1]
                            xmax_dis = answer_sheet['regions'][j]['bounding_box']['xmax'] - \
                                       Score_last[i]['model_box'][2]
                            ymax_dis = answer_sheet['regions'][j]['bounding_box']['ymax'] - \
                                       Score_last[i]['model_box'][3]
                            if xmin_dis > -30 and ymin_dis > -30 and xmax_dis < 30 and ymax_dis < 30:
                                if Score_last[i]['number_score'] != -1 and 'number' in answer_sheet['regions'][j].keys():
                                    answer_sheet['regions'][j]['default_points'] = len(answer_sheet['regions'][j]['number']) * [float(Score_last[i]['number_score'])]
                                elif Score_last[i]['number_score'] == -1 and Score_last[i]['score'] != -1 and 'number' in answer_sheet['regions'][j].keys():
                                    count_choice_m = count_choice_m + len(answer_sheet['regions'][j]['number'])
                                    j_temp.append(j)
                        if j == len(answer_sheet['regions']) - 1 and j_temp !=[]:
                            for index ,jj in enumerate(j_temp):
                                num_score_m = round(float(Score_last[i]['score'] / count_choice_m),1)
                                answer_sheet['regions'][jj]['default_points'] = len(answer_sheet['regions'][jj]['number']) * [num_score_m]
                            break
                elif Score_last[i]['label'] == 'cloze':
                    count_cloze_s = 0
                    for j in range(len(answer_sheet['regions'])):
                        if answer_sheet['regions'][j]['class_name'] == 'cloze_s':
                            xmin_dis = answer_sheet['regions'][j]['bounding_box']['xmin'] - \
                                       Score_last[i]['model_box'][0]
                            ymin_dis = answer_sheet['regions'][j]['bounding_box']['ymin'] - \
                                       Score_last[i]['model_box'][1]
                            xmax_dis = answer_sheet['regions'][j]['bounding_box']['xmax'] - \
                                       Score_last[i]['model_box'][2]
                            ymax_dis = answer_sheet['regions'][j]['bounding_box']['ymax'] - \
                                       Score_last[i]['model_box'][3]
                            if xmin_dis > -30 and ymin_dis > -30 and xmax_dis < 30 and ymax_dis < 30:
                                if Score_last[i]['number_score'] != -1 :
                                    answer_sheet['regions'][j]['default_points'] = Score_last[i]['number_score']
        elif choice_m_boxs !=[]:
            x_choice_m_min = 10000
            y_choice_m_min = 10000
            x_choice_m_max = 0
            y_choice_m_max = 0
            test = {}
            for index_m, choice_m_s in enumerate(choice_m_boxs):
                if int(choice_m_s['xmin']) < x_choice_m_min:
                    x_choice_m_min = int(choice_m_s['xmin'])
                if int(choice_m_s['ymin']) < y_choice_m_min:
                    y_choice_m_min = int(choice_m_s['ymin'])
                if int(choice_m_s['xmax']) > x_choice_m_max:
                    x_choice_m_max = int(choice_m_s['xmax'])
                if int(choice_m_s['ymax']) > y_choice_m_max:
                    y_choice_m_max = int(choice_m_s['ymax'])
            # 模型输出没有choice的情况下暂时假定只有一个choice
            type_score_choice_m = -1
            for index_t1, type_score_s1 in enumerate(type_score_boxs):
                if type_score_s1[0] < x_choice_m_max and type_score_s1[3] < y_choice_m_min:
                    type_score_choice_m = type_score_s1
                    break
            if type_score_choice_m != -1:
                test_result1 = {'min_choice_m': -1,
                                  'bounding_box': choice_m_boxs,
                                  'label': 'choice_m',
                                  'type_box': type_score_choice_m}
                type_score_flag = 0
                type_score_dict_ocrs = {}
                try:  # tr_OCR
                    print('tr_OCR')
                    image_choice = image_src.crop((type_score_boxs[0][0], type_score_boxs[0][1], type_score_boxs[0][2], type_score_boxs[0][3]))
                    res1 = tr.run(image_choice)
                    for i in range(len(res1)):
                        if res1[i][1].find('分') != -1:
                            type_score_dict_ocrs['words'] = res1[i][1]
                        elif i == len(res1):
                            for ii in range(len(res1)):
                                if res1[i][1].find('题') != -1 or res1[i][1].find('.') != -1 or res1[i][1].find(
                                        '、') != -1:
                                    type_score_dict_ocrs['words'] = res1[i][1]
                                else:
                                    continue
                except Exception as e:  # baidu_OCR
                    print('baidu_OCR')
                    res1 = get_ocr_text_and_coordinate_in_google_format(
                        img0[type_score_boxs[0][1]:type_score_boxs[0][3], type_score_boxs[0][0]:type_score_boxs[0][2]], ocr_accuracy=OCR_ACCURACY,
                        language_type='CHN_ENG')
                    for i in range(len(res1['words'])):
                        if res1['words'][i].find('分') != -1:
                            type_score_dict_ocrs['words'] = res1['words'][i]
                        elif i == len(res1):
                            for ii in range(len(res1['words'])):
                                if res1['words'][i].find('题') != -1 or res1['words'][i][1].find('.') != -1 or \
                                        res1['words'][
                                            i].find('、') != -1:
                                    type_score_dict_ocrs['words'] = res1['words'][i]
                                else:
                                    continue
                if type_score_dict_ocrs != {}:
                    test = key_words(type_score_dict_ocrs, type_score_flag)
                choice_m_score = -1
                if test == {}:
                    ### 添加返回值OCR结果
                    add_ocr = {}
                    add_ocr['model_box'] = test_result1['bounding_box']
                    add_ocr['label'] = test_result1['label']
                    add_ocr['number'] = -1
                    add_ocr['score'] = -1
                    add_ocr['number_score'] = -1
                    add_ocr['counts'] = -1
                    add_ocr['ocr'] = test_result1['words']
                    Score_last.append(add_ocr)
                elif test['volume_structure'] == -1 and test['Score_structure'] == -1:
                    ### 添加返回值OCR结果
                    add_ocr = {}
                    add_ocr['model_box'] = test_result1['bounding_box']
                    add_ocr['label'] = test_result1['label']
                    add_ocr['number'] = -1
                    add_ocr['score'] = -1
                    add_ocr['number_score'] = -1
                    add_ocr['counts'] = -1
                    add_ocr['ocr'] = test_result1['words']
                    Score_last.append(add_ocr)
                else:
                    if test['volume_structure'] != -1 and test['volume_structure'][0]['volume_score'] != -1:
                        choice_m_score = test['volume_structure'][0]['volume_score']
                    elif test['volume_structure'] == -1 and test['Score_structure'] != -1 and test['Score_structure'][0]['item_score'] != -1:
                        choice_m_score = test['Score_structure'][0]['item_score']
                if choice_m_score != -1:
                    for j in range(len(answer_sheet['regions'])):
                        if answer_sheet['regions'][j]['class_name'] == 'choice_m':
                            answer_sheet['regions'][j]['default_points'] = len(
                                answer_sheet['regions'][j]['number']) * [float(choice_m_score)]

        '''分数与模型对应'''
        for i in range(len(answer_sheet['regions'])):
            for j in range(len(Score_last)):
                if (Score_last[j]['model_box'][0] == answer_sheet['regions'][i]['bounding_box']['xmin']
                        and Score_last[j]['model_box'][1] == answer_sheet['regions'][i]['bounding_box']['ymin']
                        and Score_last[j]['model_box'][2] == answer_sheet['regions'][i]['bounding_box']['xmax']
                        and Score_last[j]['model_box'][3] == answer_sheet['regions'][i]['bounding_box']['ymax']):
                    if Score_last[j]['number'] != -1:
                        answer_sheet['regions'][i]['number'] = Score_last[j]['number']  # 题号
                    if Score_last[j]['score'] != -1:
                        # score = Score_last[j]['score']
                        # try:
                        #     length = len(answer_sheet['regions'][i]['number'])
                        #     answer_sheet['regions'][i]['default_points'] = length * [score]
                        # except Exception:
                        #     answer_sheet['regions'][i]['default_points'] = score
                        answer_sheet['regions'][i]['default_points'] = Score_last[j]['score']
                        if type(answer_sheet['regions'][i]['default_points']) is list and (
                                answer_sheet['regions'][i]['class_name'] == 'solve' or answer_sheet['regions'][i][
                            'class_name'] == 'solve0'):
                            answer_sheet['regions'][i]['class_name'] = 'optional_solve'
                        # answer_sheet['regions'][i]['number_score'] = Score_last[j]['number_score']  # 小题分数
                        # answer_sheet['regions'][i]['counts'] = Score_last[j]['counts']  # 小题个数
                    if 'ocr' in Score_last[j]:  # 没有识别到分数的模块添加type_score_ocr结果
                        answer_sheet['regions'][i]['type_score_ocr'] = Score_last[j]['ocr']
    return answer_sheet