Example #1
0
def detect_functions(symbols, original_img):
    sub_symbol_cnt = 3
    for j in range(2):
        stride = sub_symbol_cnt - j

        length = len(symbols)
        i = 0
        t_symbols = []
        locations = [x['location'] for x in symbols]
        while i < length - stride + 1:
            location = tools.join_locations(locations[i:i + stride])
            segment_img = tools.extract_img(location, original_img)
            segment = {
                'src_img': segment_img,
                'start_index': i,
                'end_index': i + 3,
                'location': location
            }
            t_symbols.append(segment)
            i = i + 1
        # print([x['start_index'] for x in t_symbols])
        img_to_predict = [x['src_img'] for x in t_symbols]
        # 识别字符 这里每次都需要calling model,可以进一步优化
        predict_input_fn = tf.estimator.inputs.numpy_input_fn(
            x={"x": tools.normalize_matrix_value(img_to_predict)},
            shuffle=False)
        predictions = tools.cnn_symbol_classifier.predict(
            input_fn=predict_input_fn)
        characters = []
        for i, p in enumerate(predictions):
            candidates = tools.get_candidates(p['probabilities'])
            characters.append(candidates[0])
        # print(characters)
        length = len(t_symbols)
        i = 0
        shift = 0

        while i < length:
            # 如果识别结果是函数,则替换为一个整体
            if characters[i]['symbol'] in config.FUNCTION and characters[i][
                    'probability'] > 0.9:
                start_index = t_symbols[i]['start_index']
                end_index = t_symbols[i]['end_index']
                # print('detect function',i,start_index,end_index,shift)
                start_index = start_index - shift
                end_index = end_index - shift
                for j in range(end_index - start_index):
                    symbols.remove(symbols[start_index])
                symbols.insert(start_index, t_symbols[i])
                shift = shift + end_index - start_index - 1
                if i + 2 < length:
                    i = i + 2
                elif i + 1 < length:
                    i = i + 1

            i = i + 1
    return symbols
Example #2
0
def get_token(characters,start_index=0):
    token = []
    token_string = ''
    index = start_index
    state = DFA_STATE['START']
    token_type = config.TOKEN_TYPE['ERROR']
    coefficient = 1
    char_cnt = 0
    while(state != DFA_STATE['DONE'] and index <= len(characters)):
        c,index,char_cnt = get_next_char(characters,index,char_cnt)
        # print('自动机状态:',get_keys(config.DFA_STATE,state),' 字符:',c,' 索引:',index)
        save = True
        if state == DFA_STATE['START']:
            if c.isdigit():
                state = DFA_STATE['INCONSTANT']
            else:
                state = DFA_STATE['DONE']
                if c in config.RESERVE:
                    token_type = config.TOKEN_TYPE['RESERVE']
                elif c in config.VARIABLE:
                    token_type = config.TOKEN_TYPE['VARIABLE']
                elif c in config.FUNCTION:
                    token_type = config.TOKEN_TYPE['FUNCTION']
                elif c in config.OPERATOR:
                    token_type = config.TOKEN_TYPE['OPERATOR']
                elif c in config.SPECIAL:
                    token_type = config.TOKEN_TYPE['SPECIAL']
                elif c in config.CMP:
                    token_type = config.TOKEN_TYPE['CMP']
                elif c == '#':
                    token_type = config.TOKEN_TYPE['END']
                elif c == 'f':
                    token_type = config.TOKEN_TYPE['OPERATOR']
                elif c == 'int':
                    token_type = config.TOKEN_TYPE['OPERATOR']
                else:
                    token_type = config.TOKEN_TYPE['ERROR']
        elif state == DFA_STATE['INCONSTANT']:
            if c == '.':
                state = DFA_STATE['INDECIMAL']
            elif c.isdigit():
                state = DFA_STATE['INCONSTANT']
            elif c in config.RESERVE:
                state = DFA_STATE['INRESERVE']
            elif c in config.VARIABLE:
                state = DFA_STATE['INVARIABLE']
            else:
                save = False
                token_type = config.TOKEN_TYPE['CONSTANT_INTEGER']
                state = DFA_STATE['DONE']
        elif state == DFA_STATE['INDECIMAL']:
            if c.isdigit():
                state = DFA_STATE['INDECIMAL']
            elif c in config.RESERVE:
                state = DFA_STATE['INRESERVE']
            elif c in config.VARIABLE:
                state = DFA_STATE['INVARIABLE']
            else:
                save = False
                token_type = config.TOKEN_TYPE['CONSTANT_DECIMAL']
                state = DFA_STATE['DONE']
        elif state == DFA_STATE['INVARIABLE']:
            save = False
            state = DFA_STATE['DONE']
            token_type = config.TOKEN_TYPE['VARIABLE']
            coefficient = token_string[0:-1]
            token_string = token_string[-1]
        elif state == DFA_STATE['INRESERVE']:
            save = False
            state = DFA_STATE['DONE']
            token_type = config.TOKEN_TYPE['RESERVE']
            coefficient = token_string[0:-1]
            token_string = token_string[-1]
        else:
            raise(ValueError,'未处理的自动机状态')

        if state == DFA_STATE['DONE'] and not save:
                index -= 1
        if save :
            token_string += c
    # 合并多个symbol组合成的token,变成一个大矩形
    if characters[index-1]['candidates'][0]['symbol'] == 'x':
        location = join_locations([x['location'] for x in characters[index-1:index]])
    else:
        location = join_locations([x['location'] for x in characters[start_index:index]])
    token = {'location':location,'token_string':token_string,
             'token_type':token_type}
    if(token_type == config.TOKEN_TYPE['RESERVE'] or token_type == config.TOKEN_TYPE['VARIABLE']):
        token = {'location': location, 'token_string': token_string,
                 'token_type': token_type,
                 'coefficient': coefficient}
    # print('token,index=',token,index)
    return token,index
Example #3
0
def detect_uncontinous_symbols(symbols, original_img):
    # 先对symbols垂直投影
    # 然后垂直投影
    for projection_type in range(1):
        projection = tools.get_projection(symbols, projection_type)
        # print('projection',projection)
        # 根据投影对symbols进行分割
        # 对于每一个分割,获得在这个分割里面的symbols
        locations = [x['location'] for x in symbols]
        end_index = 0
        for line_segment in projection:
            # 确定属于line_segment的symbols
            start_index = end_index
            for end_index in range(start_index, len(locations)):
                x11, x12 = locations[end_index][projection_type], locations[
                    end_index][projection_type] + locations[end_index][
                        projection_type + 2]
                x21, x22 = line_segment[0], line_segment[1]
                if (x11 >= x21 and x12 <= x22):
                    end_index += 1
                else:
                    break
            # 截取characters[start_index:end_index],如果长度大于1,继续递归调用sort_characters排序
            location_segment = locations[start_index:end_index]
            symbol_segment = symbols[start_index:end_index]
            sub_symbol = [x['src_img'] for x in symbol_segment]
            # print('切割后的location', location_segment)
            # print(symbol_segment)
            # 如果一个分割的长度大于1,小于3,就送到分类器进行识别
            if (len(location_segment) > 1 and len(location_segment) < 4):

                location = tools.join_locations(location_segment)
                # 从原图提取待识别的图片
                extracted_img = tools.extract_img(location, original_img)
                # 识别字符 这里每次都需要calling model,可以进一步优化
                predict_input_fn = tf.estimator.inputs.numpy_input_fn(
                    x={
                        "x":
                        tools.normalize_matrix_value([extracted_img] +
                                                     sub_symbol)
                    },
                    shuffle=False)
                predictions = tools.cnn_symbol_classifier.predict(
                    input_fn=predict_input_fn)
                characters = []
                for i, p in enumerate(predictions):
                    # print(p['classes'],FILELIST[p['classes']])
                    candidates = tools.get_candidates(p['probabilities'])
                    characters.append({'candidates': candidates})
                # print('detect uncontinuous symbols',characters)
                # 如果识别出候选的匹配字符中存在非连续字符,即作为一个整体
                for candidate in characters[0]['candidates']:
                    recognized_symbol = candidate['symbol']
                    probability = candidate['probability']

                    # 如果是非黏连字符,且有半成把握认为是正确的,则合并它们作为一个整体,返回合并后的symbols
                    if recognized_symbol in config.UNCONTINOUS_SYMBOLS and probability > 0.5:
                        # print('yesssssss',characters[2]['candidates'][0]['symbol'],characters[1]['candidates'][0]['symbol'].isdigit(),characters[3]['candidates'][0]['symbol'].isdigit())
                        # 除号必须有三个字符构成,还要判断子字符包不包含数字,如果包含数字,则不能合并为整体
                        if recognized_symbol == 'div' and len(characters) == 4 and \
                                characters[2]['candidates'][0]['symbol'] in ['-',',','point'] and \
                                characters[1]['candidates'][0]['symbol'].isdigit() == False and \
                                characters[3]['candidates'][0]['symbol'].isdigit() == False:
                            joined_symbol = {
                                'location': location,
                                'src_img': extracted_img
                            }

                            for i in range(end_index - start_index):
                                symbols.remove(symbols[start_index])
                                locations.remove(locations[start_index])
                            symbols.insert(start_index, joined_symbol)
                            locations.insert(start_index, location)
                            end_index = start_index + 1
                            break
                        # 等于号的两个子字符必须是-
                        elif recognized_symbol == '=' and len(characters) == 3 and \
                                characters[2]['candidates'][0]['symbol'] in ['-',',','point'] and \
                                characters[1]['candidates'][0]['symbol'] in ['-',',','point']:
                            joined_symbol = {
                                'location': location,
                                'src_img': extracted_img
                            }
                            for i in range(end_index - start_index):
                                symbols.remove(symbols[start_index])
                                locations.remove(locations[start_index])
                            symbols.insert(start_index, joined_symbol)
                            locations.insert(start_index, location)
                            end_index = start_index + 1
                            break
                        # 等于号的两个子字符必须是-
                        elif recognized_symbol == 'rightarrow' and len(characters) == 3 and \
                             characters[2]['candidates'][0]['symbol'] in [')', '>'] and \
                             characters[1]['candidates'][0]['symbol'] in ['-', ',', 'point']:
                            joined_symbol = {
                                'location': location,
                                'src_img': extracted_img
                            }
                            for i in range(end_index - start_index):
                                symbols.remove(symbols[start_index])
                                locations.remove(locations[start_index])
                            symbols.insert(start_index, joined_symbol)
                            locations.insert(start_index, location)
                            end_index = start_index + 1
                            break
    return symbols