from segment.sheet_resolve.tools import utils
from segment.sheet_resolve.tools.brain_api import get_ocr_text_and_coordinate, get_ocr_text_and_coordinate0
import numpy as np
import re, os
import xml.etree.cElementTree as ET
import cv2


def combine_char(all_digital_list):
    new_all_digital_list = []
    i = 1
    while i <= len(all_digital_list):
        pre_one = all_digital_list[i - 1]
        if i == len(all_digital_list):
            new_all_digital_list.append(pre_one)
            break
        rear_one = all_digital_list[i]
        condition1 = abs(pre_one['location']['top'] - rear_one['location']['top']) < pre_one['location'][
            'height']  # 两字高度差小于一字高度
        condition2 = pre_one['location']['left'] + 1.8 * pre_one['location']['width'] > rear_one['location'][
            'left']  # 某字宽度的2倍大于两字间间隔
        if condition1:
            if condition2:
                new_char_list = [pre_one, rear_one]
                new_char_list = sorted(new_char_list, key=lambda k: k.get('location')['left'])
                pre_one = new_char_list[0]
                rear_one = new_char_list[1]
                new_char = pre_one['char'] + rear_one['char']
                new_location = {'left': pre_one['location']['left'],
                                'top': min(pre_one['location']['top'], rear_one['location']['top']),
                                'width': rear_one['location']['left'] + rear_one['location']['width'] -
                                         pre_one['location']['left'],
                                'height': max(pre_one['location']['height'], rear_one['location']['height'])}
                new_all_digital_list.append({'char': new_char, 'location': new_location})
                i = i + 1 + 1
            else:
                new_all_digital_list.append(pre_one)
                i = i + 1
        else:
            new_all_digital_list.append(pre_one)  # 遇到字符y轴相差过大就结束
            i = i + 1
    return new_all_digital_list


def get_x_diff_and_y_diff0(single_choice_m_coordinates):
    single_choice_m_matrix = np.array(single_choice_m_coordinates)
    x_diff = single_choice_m_matrix[1:, 0] - single_choice_m_matrix[:-1, 2]
    x_diff_ = [ele for ele in x_diff.tolist() if ele < 0]
    xx = [ele for ele in x_diff.tolist() if ele not in x_diff_]
    x_interval = int(np.mean(xx))
    return x_interval


def get_x_diff_and_y_diff(single_choice_m_coordinates):
    single_choice_m_matrix = np.array(single_choice_m_coordinates)
    x_diff = single_choice_m_matrix[1:, 0] - single_choice_m_matrix[:-1, 2]
    x_diff_ = [ele for ele in x_diff.tolist() if ele < 0]
    xx = [ele for ele in x_diff.tolist() if ele not in x_diff_]
    x_dif_length = int(np.mean(xx))

    yy_diff = single_choice_m_matrix[1:, 1] - single_choice_m_matrix[:-1, 3]
    y_diff_ = [ele for ele in yy_diff.tolist() if ele < 0]
    yy = [ele for ele in yy_diff.tolist() if ele not in y_diff_]
    y_dif_length = int(np.mean(yy))
    x_y_interval = (x_dif_length, y_dif_length)
    return x_y_interval


def choice_bbox_vague(choice_m_absolute_box, x_y_interval, single_width, single_height, direction):
    xmin0 = [ele[0] for ele in choice_m_absolute_box]
    ymin0 = [ele[1] for ele in choice_m_absolute_box]
    xmax0 = [ele[2] for ele in choice_m_absolute_box]
    ymax0 = [ele[3] for ele in choice_m_absolute_box]

    if direction == 180:
        x_diff = x_y_interval[0]
        s_width = single_height
        choice_bbox = (np.hstack((np.array([min(xmin0) - x_diff - s_width, min(ymin0)]), np.array([max(xmax0), max(ymax0)])))).tolist()
        return choice_bbox
    elif direction == 90:
        y_diff = x_y_interval[1]
        s_height = single_width
        choice_bbox = (np.hstack((np.array([min(xmin0), min(ymin0) - y_diff - s_height]), np.array([max(xmax0), max(ymax0)])))).tolist()
        return choice_bbox


def get_digital_near_choice_m_box(new_all_digital_list, choice_m_new_bbox, x_y_interval_ave, singe_box_width_height_ave, direction):
    digital_list_by_choice_m = []

    for i, c_ele in enumerate(choice_m_new_bbox):
        c_box = c_ele['bounding_box']
        title_number_list = []
        title_number_dict = {}
        for j, d_ele in enumerate(new_all_digital_list):
            d_location = d_ele['location']
            if direction == 180:
                if utils.decide_coordinate_left(d_location, c_box, x_y_interval_ave, singe_box_width_height_ave) == True:
                    title_number_list.append(d_ele)
            elif direction == 90:
                if utils.decide_coordinate_top(d_location, c_box, x_y_interval_ave, singe_box_width_height_ave) == True:
                    title_number_list.append(d_ele)

        title_number_dict['bounding_box'] = c_box
        title_number_dict['title_number'] = title_number_list

        digital_list_by_choice_m.append(title_number_dict)

    return digital_list_by_choice_m


def move_intersect_box(all_small_coordinate_list):
    all_small_coordinate_list = sorted(all_small_coordinate_list, key=lambda k: k[0])
    all_small_coordinate_list_temp = all_small_coordinate_list.copy()

    del_list = []
    new_box = []
    for i, outer in enumerate(all_small_coordinate_list_temp):
        for j, inner in enumerate(all_small_coordinate_list_temp):
            if i == j:
                continue
            else:
                if utils.get_min_distance(inner, outer) == 'i':
                    inner_outer_list = [inner, outer]
                    inner_outer_list = sorted(inner_outer_list, key=lambda k: k[0])

                    if abs(inner_outer_list[0][2] - inner_outer_list[1][0]) > int(inner[2] - inner[0]) // 4:
                        del_list.append(inner)
                        del_list.append(outer)
                        new_box_xmin = (inner[0] + outer[0]) // 2
                        new_box_ymin = (inner[1] + outer[1]) // 2
                        new_box_xmax = (inner[2] + outer[2]) // 2
                        new_box_ymax = (inner[3] + outer[3]) // 2
                        new_box.append([new_box_xmin, new_box_ymin, new_box_xmax, new_box_ymax])
                    else:
                        continue
    del_list0 = [list(t) for t in set(tuple(ele) for ele in del_list)]
    del_list0.sort(key=del_list.index)
    new_list0 = [list(t) for t in set(tuple(ele) for ele in new_box)]
    new_list0.sort(key=new_box.index)

    all_small_coordinate = []
    for ele in all_small_coordinate_list_temp:
        if ele in all_small_coordinate_list_temp:
            if ele not in del_list0:
                all_small_coordinate.append(ele)
    for ele in new_list0:
        all_small_coordinate.append(ele)
    return all_small_coordinate


def get_one_line_box(all_small_coordinate_list, height):
    all_small_coordinate_raw = sorted(all_small_coordinate_list, key=lambda k: k[1])
    all_small_coordinate_raw_array = np.array(all_small_coordinate_raw)

    pre = all_small_coordinate_raw_array[1:, 1]
    rear = all_small_coordinate_raw_array[:-1, 1]
    y_diff = rear - pre
    index_list = [index for index, ele in enumerate(y_diff) if ele < 0 and abs(ele) > height // 3]

    res_list = []
    split_x_index = [ele + 1 for ele in index_list]
    split_x_index.insert(0, 0)
    split_x_index.insert(-1, len(all_small_coordinate_raw))
    split_x_index = sorted(list(set(split_x_index)))
    for i, split in enumerate(split_x_index[1:]):
        one_line = all_small_coordinate_raw[split_x_index[i]:split_x_index[i + 1]]
        one_line = sorted(one_line, key=lambda k: k[0])
        res_list.append(one_line)
    return res_list


def get_one_col_box(all_small_coordinate_list, width):
    all_small_coordinate_raw = sorted(all_small_coordinate_list, key=lambda k: k[0])
    all_small_coordinate_raw_array = np.array(all_small_coordinate_raw)

    pre = all_small_coordinate_raw_array[1:, 0]
    rear = all_small_coordinate_raw_array[:-1, 0]
    y_diff = rear - pre
    index_list = [index for index, ele in enumerate(y_diff) if ele < 0 and abs(ele) > width // 3]

    res_list = []
    split_x_index = [ele + 1 for ele in index_list]
    split_x_index.insert(0, 0)
    split_x_index.insert(-1, len(all_small_coordinate_raw))
    split_x_index = sorted(list(set(split_x_index)))
    for i, split in enumerate(split_x_index[1:]):
        one_line = all_small_coordinate_raw[split_x_index[i]:split_x_index[i + 1]]
        one_line = sorted(one_line, key=lambda k: k[0])
        res_list.append(one_line)
    return res_list


def analysis_s_box(choice_m_bbox_list):
    choice_m_box_dict = []
    for index, s_choice_m_dict in enumerate(choice_m_bbox_list):
        if s_choice_m_dict['rows'] == 1:
            choice_m_box_dict.append(s_choice_m_dict)
        else:
            all_small_coordinate_list0 = [[ele['xmin'], ele['ymin'], ele['xmax'], ele['ymax']] for ele in s_choice_m_dict['all_small_coordinate']]
            all_small_coordinate_raw0 = sorted(all_small_coordinate_list0, key=lambda k: k[1])
            all_small_coordinate_raw_array0 = np.array(all_small_coordinate_raw0)
            s_box_wid_hei = (
                int(np.mean(all_small_coordinate_raw_array0[:, 2])) - int(np.mean(all_small_coordinate_raw_array0[:, 0])),
                int(np.mean(all_small_coordinate_raw_array0[:, 3])) - int(np.mean(all_small_coordinate_raw_array0[:, 1])))

            all_small_coordinate_list = move_intersect_box(all_small_coordinate_list0)

            all_small_coordinate_raw = sorted(all_small_coordinate_list, key=lambda k: k[1])
            all_small_coordinate_raw_array = np.array(all_small_coordinate_raw)

            pre = all_small_coordinate_raw_array[1:, 1]
            rear = all_small_coordinate_raw_array[:-1, 1]
            y_diff = rear - pre
            index_list = [index for index, ele in enumerate(y_diff) if ele < 0 and abs(ele) > s_box_wid_hei[1]//3]

            res_list = []
            split_x_index = [ele + 1 for ele in index_list]
            split_x_index.insert(0, 0)
            split_x_index.insert(-1, len(all_small_coordinate_raw))
            split_x_index = sorted(list(set(split_x_index)))
            for i, split in enumerate(split_x_index[1:]):
                one_line = all_small_coordinate_raw[split_x_index[i]:split_x_index[i + 1]]
                one_line = sorted(one_line, key=lambda k: k[0])
                res_list.append(one_line)

            one_line_list = []
            for index1, ele1 in enumerate(res_list):
                if len(ele1) == s_choice_m_dict['cols']:
                    one_line_list.append(ele1)
            s_box_all = [ele0 for ele in one_line_list for ele0 in ele]
            if s_box_all == []:
                x_y_interval = int((s_choice_m_dict['single_width'] * 2) // 3)
            else:
                x_y_interval = []
                if len(one_line_list) > 1:
                    x_y_interval = get_x_diff_and_y_diff0(s_box_all)
                elif len(one_line_list) == 1:
                    s_box_arr = np.array(s_box_all)
                    rear = s_box_arr[1:, 0]
                    pre = s_box_arr[:-1, 2]
                    x_y_interval = int(np.mean(rear - pre))
                elif len(one_line_list) == []:
                    x_y_interval = get_x_diff_and_y_diff0(all_small_coordinate_raw)

            all_small_coordinate = []
            res_list = sorted(res_list, key=lambda k: k[0])
            for index, box_list in enumerate(res_list):
                for s_box in box_list:
                    all_small_coordinate.append(s_box)
                if len(box_list) == s_choice_m_dict['cols']:
                    continue
                else:
                    one_line_xmin = [ele[0] for ele in box_list]
                    choice_m_xmin = s_choice_m_dict['bounding_box']['xmin']
                    exist_index_all = []
                    for exist_index, exist_xmin in enumerate(one_line_xmin):
                        if abs(choice_m_xmin - exist_xmin) <= s_box_wid_hei[0]:
                            exist_index_all.append(0)
                        else:
                            k = round(abs(choice_m_xmin - exist_xmin) / (s_box_wid_hei[0] + x_y_interval))
                            exist_index_all.append(k)

                    s_box_index_all = [ele for ele in range(s_choice_m_dict['cols'])]
                    lack_index = [ele for ele in s_box_index_all if ele not in exist_index_all]
                    if 0 in exist_index_all:
                        for lack_ele in lack_index:
                            xmin = box_list[0][0] + lack_ele * (s_box_wid_hei[0] + x_y_interval)
                            ymin = box_list[0][1]
                            xmax = xmin + s_box_wid_hei[0]
                            ymax = box_list[0][3]
                            all_small_coordinate.append([xmin, ymin, xmax, ymax])
                    elif (s_choice_m_dict['cols'] - 1) in exist_index_all:
                        for lack_ele in lack_index:
                            xmin = box_list[-1][0] - (s_choice_m_dict['cols'] - 1 - lack_ele) * (s_box_wid_hei[0] + x_y_interval)
                            ymin = box_list[-1][1]
                            xmax = xmin + s_box_wid_hei[0]
                            ymax = box_list[-1][3]
                            all_small_coordinate.append([xmin, ymin, xmax, ymax])
                    elif 1 in exist_index_all:
                        for lack_ele in lack_index:
                            if lack_ele < 1:
                                xmin = box_list[0][0] - (s_box_wid_hei[0] + x_y_interval)
                                ymin = box_list[0][1]
                                xmax = xmin + s_box_wid_hei[0]
                                ymax = box_list[0][3]
                                all_small_coordinate.append([xmin, ymin, xmax, ymax])
                            else:
                                xmin = box_list[0][0] + (lack_ele - 1) * (s_box_wid_hei[0] + x_y_interval)
                                ymin = box_list[0][1]
                                xmax = xmin + s_box_wid_hei[0]
                                ymax = box_list[0][3]
                                all_small_coordinate.append([xmin, ymin, xmax, ymax])
            all_small_coordinate0 = []
            for s_bbox in all_small_coordinate:
                location = {}
                location['xmin'] = s_bbox[0]
                location['ymin'] = s_bbox[1]
                location['xmax'] = s_bbox[2]
                location['ymax'] = s_bbox[3]
                all_small_coordinate0.append(location)
            s_choice_m_dict.update({'all_small_coordinate': all_small_coordinate0})
            choice_m_box_dict.append(s_choice_m_dict)
    return choice_m_box_dict


def get_title_number(choice_bbox, choice_region, choice_m_box_dict, direction):
    words_result_choice = get_ocr_text_and_coordinate0(choice_region, ocr_accuracy='accurate', language_type='CHN_ENG')
    all_digital_list0 = []
    pattern = re.compile(r'\d')
    for i, chars_dict in enumerate(words_result_choice):
        chars_list = chars_dict['chars']
        for ele in chars_list:
            if pattern.search(ele['char']):
                all_digital_list0.append(ele)

    # tree = ET.parse(r'C:\Users\admin\Desktop\exam_segment_django113\segment\exam_info\000000-template.xml')  # xml tree
    # for index, bbox in enumerate(all_digital_list0):
    #     # bbox0 = region_info['bbox']
    #     location = bbox['location']
    #     xmin = location['left']
    #     ymin = location['top']
    #     xmax = location['left'] + location['width']
    #     ymax = location['top'] + location['height']
    #     tree = utils.create_xml(bbox['char'], tree, xmin, ymin, xmax, ymax)
    # tree.write(r'C:\Users\admin\Desktop\exam_segment_django113\segment\exam_image\sheet\arts_comprehensive\2020-02-05\choice_region_00.xml')

    delete_list = []
    for ele_digtal in all_digital_list0:
        for ele_choice_m in choice_m_box_dict:
            xmin_d = ele_digtal['location']['left']
            ymin_d = ele_digtal['location']['top']
            xmax_d = ele_digtal['location']['left'] + ele_digtal['location']['width']
            ymax_d = ele_digtal['location']['top'] + ele_digtal['location']['height']

            ele_digtal_bbox = [xmin_d, ymin_d, xmax_d, ymax_d]

            ele_choice_m_bbox = [ele_choice_m['bounding_box']['xmin'], ele_choice_m['bounding_box']['ymin'],
                                 ele_choice_m['bounding_box']['xmax'], ele_choice_m['bounding_box']['ymax']]

            choice_m_new_box = utils.get_img_region_box1(ele_choice_m_bbox, choice_bbox)
            if utils.decide_coordinate_full_contains2(choice_m_new_box, ele_digtal_bbox) == True:
                delete_list.append(ele_digtal)

    all_digital_list = []

    for ele in all_digital_list0:
        if ele in delete_list:
            continue
        else:
            all_digital_list.append(ele)

    # new_all_digital_list = combine_char(all_digital_list)
    #
    # tree = ET.parse(r'C:\Users\admin\Desktop\exam_segment_django113\segment\exam_info\000000-template.xml')  # xml tree
    # for index, bbox in enumerate(new_all_digital_list):
    #     # bbox0 = region_info['bbox']
    #     location = bbox['location']
    #     xmin = location['left']
    #     ymin = location['top']
    #     xmax = location['left'] + location['width']
    #     ymax = location['top'] + location['height']
    #     tree = utils.create_xml(bbox['char'], tree, xmin, ymin, xmax, ymax)
    # tree.write(r'C:\Users\admin\Desktop\exam_segment_django113\segment\exam_image\sheet\arts_comprehensive\2020-02-05\choice_region_0.xml')

    choice_m_box_dict_new = []
    x_y_interval_all = []
    s_box_w_h = []
    for index, s_choice_m_box in enumerate(choice_m_box_dict):
        choice_m_box = [s_choice_m_box['bounding_box']['xmin'], s_choice_m_box['bounding_box']['ymin'],
                        s_choice_m_box['bounding_box']['xmax'], s_choice_m_box['bounding_box']['ymax']]
        choice_m_new_box = utils.get_img_region_box1(choice_m_box, choice_bbox)
        all_small_coordinate_dict = s_choice_m_box['all_small_coordinate']
        all_small_coordinate_list = [[ele['xmin'], ele['ymin'], ele['xmax'], ele['ymax']] for ele in
                                     all_small_coordinate_dict]
        all_small_coordinate_new = []
        for s_bbox in all_small_coordinate_list:
            s_bbox_new = utils.get_img_region_box1(s_bbox, choice_bbox)
            all_small_coordinate_new.append(s_bbox_new)
        col = s_choice_m_box['cols']
        rows = s_choice_m_box['rows']
        rows_list = [ele['rows'] for ele in choice_m_box_dict if ele['rows'] == 1]
        if len(rows_list) == len(choice_m_box_dict):
            w_list = [ele['single_width'] for ele in choice_m_box_dict]
            h_list = [ele['single_height'] for ele in choice_m_box_dict]
            w_arr = np.array(w_list)
            h_arr = np.array(h_list)
            s_box_wid_hei = ((int(np.mean(w_arr)), int(np.mean(h_arr))))
            s_box_w_h.append(s_box_wid_hei)
            x_y_interval = s_box_wid_hei
            x_y_interval_all.append(x_y_interval)
            s_choice_m_box.update({'bounding_box': choice_m_new_box,
                                   'all_small_coordinate': all_small_coordinate_new,
                                   's_box_w_h': s_box_wid_hei,
                                   'x_y_interval': x_y_interval})
            choice_m_box_dict_new.append(s_choice_m_box)
        else:
            if rows == 1:
                all_small_coordinate_list = sorted(all_small_coordinate_new, key=lambda k: k[1])
                s_box_array = np.array(all_small_coordinate_list)
                s_box_wid_hei = (int(np.mean(s_box_array[:, 2])) - int(np.mean(s_box_array[:, 0])),
                                 int(np.mean(s_box_array[:, 3])) - int(np.mean(s_box_array[:, 1])))
                s_box_w_h.append(s_box_wid_hei)
                s_choice_m_box.update({'bounding_box': choice_m_new_box,
                                       'all_small_coordinate': all_small_coordinate_new,
                                       's_box_w_h': s_box_wid_hei,
                                       'x_y_interval': ('nan', 'nan')})
                choice_m_box_dict_new.append(s_choice_m_box)
            else:
                x_y_interval = utils.get_x_diff_and_y_diff1(all_small_coordinate_new, col)
                x_y_interval_all.append(x_y_interval)

                all_small_coordinate_list = sorted(all_small_coordinate_new, key=lambda k: k[1])
                s_box_array = np.array(all_small_coordinate_list)
                s_box_wid_hei = (int(np.mean(s_box_array[:, 2])) - int(np.mean(s_box_array[:, 0])),
                                 int(np.mean(s_box_array[:, 3])) - int(np.mean(s_box_array[:, 1])))
                s_box_w_h.append(s_box_wid_hei)
                s_choice_m_box.update({'bounding_box': choice_m_new_box,
                                       'all_small_coordinate': all_small_coordinate_new,
                                       's_box_w_h': s_box_wid_hei,
                                       'x_y_interval': x_y_interval})

                choice_m_box_dict_new.append(s_choice_m_box)

    x_y_interval_arr = np.array(x_y_interval_all)
    x_y_interval_ave = (int(np.mean(x_y_interval_arr[:, 0])), int(np.mean(x_y_interval_arr[:, 1])))

    s_box_w_h_arr = np.array(s_box_w_h)
    singe_box_width_height_ave = (int(np.mean(s_box_w_h_arr[:, 0])), int(np.mean(s_box_w_h_arr[:, 1])))

    digital_list_by_choice_m = get_digital_near_choice_m_box(all_digital_list0, choice_m_box_dict_new, x_y_interval_ave, singe_box_width_height_ave, direction)

    for number in digital_list_by_choice_m:
        title_number_list = number['title_number']

        all_digital_list = sorted(title_number_list, key=lambda k: k.get('location')['top'])
        new_title_number_list = combine_char(all_digital_list)
        number.update({'title_number': new_title_number_list})

    # tree = ET.parse(r'C:\Users\admin\Desktop\exam_segment_django113\segment\exam_info\000000-template.xml')  # xml tree
    # for index, bbox0 in enumerate(digital_list_by_choice_m):
    #     title_number_list = bbox0['title_number']
    #     for bbox in title_number_list:
    #         location = bbox['location']
    #         xmin = location['left']
    #         ymin = location['top']
    #         xmax = location['left'] + location['width']
    #         ymax = location['top'] + location['height']
    #         tree = utils.create_xml(bbox['char'], tree, xmin, ymin, xmax, ymax)
    # tree.write(r'C:\Users\admin\Desktop\exam_segment_django113\segment\exam_image\sheet\arts_comprehensive\2020-02-05\choice_region_0.xml')


    digital_list_by_choice_m = sorted(digital_list_by_choice_m, key=lambda k: k.get('bounding_box')[1])
    digital_list_by_choice_m = sorted(digital_list_by_choice_m, key=lambda k: k.get('bounding_box')[0])

    all_list = []
    for index0, ele0 in enumerate(choice_m_box_dict_new):
        for index1, ele1 in enumerate(digital_list_by_choice_m):
            choice_m0 = ele0['bounding_box']
            choice_m1 = ele1['bounding_box']
            if choice_m0 == choice_m1:
                ele0.update({'title_number': ele1['title_number']})
                all_list.append(ele0)

    all_list_new = []
    a_z = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    for choice_m_index, choice_m_s in enumerate(all_list):
        # if direction == 180:     # 题号vertical
        row_and_col = (choice_m_s['rows'], choice_m_s['cols'])
        title_number = choice_m_s['title_number']
        single_bbox_width_height = choice_m_s['s_box_w_h']
        s_box = choice_m_s['all_small_coordinate']
        if len(title_number) == row_and_col[0]:
            title_number_list = [int(ele['char']) for ele in title_number]
            choice_m_s.update({'title_number': title_number_list})
            all_list_new.append(choice_m_s)
        else:
            s_box = sorted(s_box, key=lambda k: k[1])
            s_box_row = get_one_line_box(s_box, single_bbox_width_height[1])
            row_box_ = []

            index_list = []  # 存在的index
            for index0, ele0 in enumerate(s_box_row):
                for index1, ele1 in enumerate(title_number):
                    title_number_bbox = [ele1['location']['left'], ele1['location']['top'],
                                         ele1['location']['left'] + ele1['location']['width'],
                                         ele1['location']['top'] + ele1['location']['height']]
                    row_box = {}
                    if title_number_bbox[1] - single_bbox_width_height[1] < ele0[0][1] < title_number_bbox[1] + \
                            single_bbox_width_height[1] \
                            and title_number_bbox[3] - single_bbox_width_height[1] < ele0[0][3] < \
                            title_number_bbox[3] + single_bbox_width_height[1]:
                        row_box['title_number'] = ele1
                        row_box['row_box'] = ele0
                        row_box_.append(row_box)
                        index_list.append(index0)
            index0 = list(set([i for i in range(0, row_and_col[0])]) - set(index_list))  # lack index
            number0 = choice_m_s['number']
            for index, exist_index in enumerate(index_list):
                number_char = choice_m_s['title_number'][index]['char']
                number0[exist_index] = int(number_char)
            new_number_list = utils.infer_number(number0)
            choice_m_s.update({'title_number': new_number_list})
            all_list_new.append(choice_m_s)
    # print(all_list_new)
    title_number_by_choice_m_list = []     # sort change coordinate
    for index, single_choice_m in enumerate(all_list_new):
        small_bbox_list = []
        for index_s, ele_s in enumerate(single_choice_m['all_small_coordinate']):
            location_s = {}
            s_box_new = utils.get_img_region_box0(ele_s, choice_bbox)
            location_s['xmin'] = s_box_new[0]
            location_s['ymin'] = s_box_new[1]
            location_s['xmax'] = s_box_new[2]
            location_s['ymax'] = s_box_new[3]
            small_bbox_list.append(location_s)

        choice_m_bbox = single_choice_m['bounding_box']
        choice_m_by_img = utils.get_img_region_box0(choice_m_bbox, choice_bbox)
        choice_m_by_img0 = utils.list_to_dict(choice_m_by_img)
        single_choice_m.update({'number': single_choice_m['title_number']})
        single_choice_m.update({'bounding_box': choice_m_by_img0,
                                'all_small_coordinate': small_bbox_list})
        single_choice_m.pop('x_y_interval')
        single_choice_m.pop('s_box_w_h')
        single_choice_m.pop('title_number')
        title_number_by_choice_m_list.append(single_choice_m)
    return title_number_by_choice_m_list
