43758c7e by 周伟奇

add general extractor

1 parent d8cec4a0
......@@ -16,4 +16,11 @@ test*
*.jpg
*.out
*.log
\ No newline at end of file
*.log
sample/
go_res/
test.py
simhei.ttf
sign_res/
res_valid.json
......
REPLACE_DICT_1 = {
"元": "圆",
# "零角": "零",
"柴": "柒",
"染": "柒",
"查": "壹",
"武": "贰",
"家": "贰",
"就": "贰",
"登": "叁",
# "@整": "叁",
"鑫": "叁",
"垂": "叁",
"捆": "捌",
"搁": "捌",
"级": "捌",
"测": "捌",
"拥": "捌",
"损": "捌",
"盒": "叁",
"摄": "捌",
"报": "捌",
"会": "叁",
"索": "壹",
"任": "仟",
"杆": "仟",
"仔": "仟",
"什": "仟",
"付": "仟",
"伴": "仟",
"宿": "佰",
"信": "佰",
"情": "佰",
"值": "佰",
"荣": "柒",
"渠": "柒",
"类": "柒",
"案": "柒",
"集": "柒",
"方": "万",
"抬": "拾",
"给": "拾",
"樟": "肆",
"单": "肆",
"邮": "肆",
"政": "玖",
"拐": "捌",
# "柴": "柒",
# "任": "仟",
# "拥": "捌",
# "会": "叁",
}
ARG_KEY_KEY_LIST = 'keys_list'
ARG_KEY_VALUE_DICT = 'values_dict'
INVOICE_KEY_LIST = [
('纳税人识别号', False), # 相近的key 0
('增值税', False), # 相近的key 1
('地', False), # 单字的key 2
('址', False), # 单字的key 3
('开票日期', '开票曰期', '开票日', True), # 4
('发票代码', '发票代鸡', True), # 5
('发票号码', '发票号瑞', '发要号瑞', True), # 6
('机打代码', False), # 7
('机打号码', '机打号玛', False), # 8
('机器编号', False), # 9
('购买方名称', '购买方名称及', False), # 10
('纳税人识别号/', False), # 11
('统一社会信用代码/', False), # 12
('身份证号码', '身份证号码/', False), # 13
('车辆类型', True), # 14
('厂牌型号', '广牌型号', '厂胖型号', '广牌型考', True), # 15
('产地', '严地', True), # 16
('合格证号', False), # 17
('进口证明书号', True), # 18
('商检单号', True), # 19
('发动机号码', False), # 20
('车辆识别代号/车架号码', True), # 21
('价税合计', '价现合计', '价“税合计', False), # 22
('小写', True), # 23 TODO 多个值时的取值
('销货单位名称', False), # 24
('电话', True), # 25
('账号', '账考', '帐号', '帐考', '张号', '陈号', '昨号', True), # 26
('开户银行', True), # 27
('增值税税率', True), # 28 value false
('或征收税', False), # 29
('税额', False), # 30
('主管税务', True), # 31 value False
('机关及代码', True), # 32
('不含税价', True), # 33 value False
('完税凭证号码', False), # 34
('开票人', True), # 35
('吨位', True), # 36
('限乘人数', '跟乘人数', True), # 37 TODO '人数'这种情况的坐标切分
('备注', True) # 38
]
# split key-value一体
# append key-value_suffix 需要坐标切分
# insert key-value_prefix 需要坐标切分
INVOICE_VALUE_DICT = {
'开票日期': {
'length': 10,
'str_type': 'date',
# idx, location, top, bottom, left, (idx, scope), choice, if_startswith
'location': [(4, 'right', 0.3, 0.5, 0, (2, ), 'xmin', 'split')],
'fix_methods': [('prune_first_char', {'char_set': {':', ':', ';', }})]
},
'发票代码': {
'length': 12,
'str_type': 'int',
'location': [(5, 'right', 0.2, 0.2, 0, (2, ), 'xmin', 'split')]
},
'发票号码': {
'length': 8,
'str_type': 'int',
'location': [(6, 'right', 0.2, 0.5, 0, (2, ), 'length', 'split')],
'fix_methods': [('prune_first_char', {'char_set': {'-',}})]
},
'机打代码': {
'length': 12,
'str_type': 'int',
'location': [(7, 'right', 0.5, 1, 0, (2, ), 'ymin', None)]
},
'机器编号': {
'length': 12,
'str_type': 'int',
'location': [(9, 'right', 0.5, 1, 0, (2, ), 'ymax', None)]
},
'机打号码': {
'length': 8,
'str_type': 'int',
'location': [(8, 'right', 0.5, 0.5, 0, (2, ), 'length', None)]
},
'购买方名称': {
'length': None,
'str_type': 'str', # cn
'location': [(10, 'right', 0.5, 0.5, 0, (11, 12, 13, 2), 'xmin', None)]
},
'纳税人识别号/统一社会信用代码/身份证号码': {
'length': 18,
'str_type': 'str', # alnum
'location': [(11, 'right', 0, 2, 0, (2.5, ), 'length', None), (12, 'right', 1, 1, 0, (2, ), 'length', None), (13, 'right', 2, 0, 0.5, (3, ), 'length', None)]
},
'车辆类型': {
'length': None,
'str_type': 'str',
'location': [(14, 'right', 0.2, 0.2, 0, (15, 1.5), 'xmin', 'split'), (15, 'left', 0.2, 0.2, 0, (14, 2.5), 'xmax', None)]
},
'厂牌型号': {
'length': None,
'str_type': 'str',
'location': [(15, 'right', 0.2, 0.2, 0, (16, 3.5), 'xmin', 'split'), (16, 'left', 0.2, 0.2, 0, (15, 2.5), 'xmax', None)]
},
'产地': {
'length': None,
'str_type': 'str', # cn
'location': [(16, 'right', 0.2, 0.2, 0, (2.5, ), 'xmin', 'split')]
},
'合格证号': {
'length': None, # 15
'str_type': 'str', # alnum
'location': [(17, 'right', 0.2, 0.2, 0, (18, 1.5), 'xmin', None), (18, 'left', 0.2, 0.2, 0, (17, 1.5), 'xmax', None)]
},
'进口证明书号': {
'length': None,
'str_type': 'str', # alnum
'location': [(18, 'right', 0.3, 0.3, 0, (19, 1.5), 'xmin', 'split'), (19, 'left', 0.2, 0.2, 0, (18, 3), 'xmax', None)]
},
'商检单号': {
'length': None,
'str_type': 'str',
'location': [(19, 'right', 0.2, 0.2, 0, (1.5, ), 'xmin', 'split')]
},
'发动机号码': {
'length': None,
'str_type': 'str', # alnum
'location': [(20, 'right', 0.2, 0.2, 0, (21, 2), 'xmin', None), (21, 'left', 0.2, 0.2, 0, (20, 1.4), 'xmax', None)]
},
'车辆识别代号/车架号码': {
'length': 17,
'str_type': 'str', # alnum
'location': [(21, 'right', 0.3, 0.3, 0, (1.2, ), 'xmin', 'split')]
},
'价税合计大写': {
'length': None,
'str_type': 'str', # cn
'location': [(22, 'right', 0.2, 0.2, 0, (23, 3), 'xmin', None), (23, 'left', 0.2, 0.2, 0, (22, 15), 'xmax', None)],
'fix_methods': [('prune_no_cn', {}), ('replace_whole', {'replace_map': REPLACE_DICT_1})]
},
'价税合计小写': {
'length': None,
'str_type': 'float',
'location': [(23, 'right', 0.4, 0.4, 0, (4, ), 'xmin', 'split')],
'fix_methods': [('prune_amount', {})]
},
'销货单位名称': {
'length': None,
'str_type': 'str', # cn
'location': [(24, 'right', 0.2, 0.2, 0, (25, 3), 'xmin', None), (25, 'left', 0.3, 0.3, 0, (24, 15), 'xmax', None)]
},
'电话': {
'length': None,
'str_type': 'str', # int + -
'location': [(25, 'right', 0.3, 0.3, 0, (5, ), 'xmin', 'split')]
},
'纳税人识别号': {
'length': None,
'str_type': 'str', # cn
'location': [(0, 'right', 0.3, 0.3, 0, (26, 2.5), 'xmin', None), (26, 'left', 0.3, 0.3, 0, (0, 15), 'xmax', None)]
},
'账号': {
'length': None,
'str_type': 'str',
'location': [(26, 'right', 0.3, 0.3, 0, (6, ), 'xmin', 'split')]
},
'地址': {
'length': None,
'str_type': 'str', # cn
'location': [(27, 'left', 0.3, 0.3, 0, (3, 4), 'merge', None), (3, 'right', 0.3, 0.3, 0, (27, 20), 'xmin', None)]
},
'开户银行': {
'length': None,
'str_type': 'str', # cn
'location': [(27, 'right', 0.3, 0.3, 0, (3, ), 'xmin', 'split')]
},
'增值税税率或征收率': {
'length': 3,
'str_type': 'str', # 13%
'location': [(28, 'right', 0, 1, 0, (1, 30, 1), 'xmin', None), (29, 'right', 1, 0, 0, (1, 30, 1), 'xmin', None),
(1, 'left', 0, 1, 0, (28, 29, 2), 'xmax', None), (30, 'left', 1, 0, 0, (28, 29, 2), 'xmax', None)],
'fix_methods': [('replace_last_char', {'char_set': {'8', '9', '号'}, 'target_char': '%'})]
},
'增值税税额': {
'length': None,
'str_type': 'float',
'location': [(1, 'right', 0, 1, 0, (31, 32, 2.5), 'xmin', None), (30, 'right', 1, 0, 0, (31, 32, 2.5), 'xmin', None),
(31, 'left', 0, 1, 0, (1, 30, 2), 'xmax', None), (32, 'left', 1, 0, 0, (1, 30, 2), 'xmax', None)],
'fix_methods': [('prune_amount', {})]
},
'主管税务机关及代码': {
'length': None,
'str_type': 'str',
'location': [(31, 'right', 0, 1.5, 0, (2, ), 'merge', None), (32, 'right', 1, 0.5, 0, (2, ), 'merge', None)]
},
'不含税价-小写': {
'length': None,
'str_type': 'float', # cn
'location': [(34, 'left', 0.3, 0.3, 0, (33, 1.5), 'xmax', None), (33, 'right', 0.2, 0.2, 0, (34, 1.5), 'xmin', None)],
'fix_methods': [('prune_amount', {})]
},
'完税凭证号码': {
'length': None,
'str_type': 'str',
'location': [(34, 'right', 0.2, 0.2, 0, (36, 1.5), 'xmin', None), (36, 'left', 0.2, 0.2, 0, (34, 6), 'xmax', None)]
},
'吨位': {
'length': None,
'str_type': 'str',
'location': [(36, 'right', 0.2, 0.2, 0, (37, 1), 'xmin', 'split'), (37, 'left', 0.2, 0.2, 0, (36, 0.5), 'xmax', None)]
},
'限乘人数': {
'length': None,
'str_type': 'int',
'location': [(37, 'right', 0.2, 0.2, 0, (0.5, ), 'xmin', 'split')]
},
'开票人': {
'length': None,
'str_type': 'str',
'location': [(35, 'right', 0, 0.5, 0, (1.5, ), 'xmin', 'split')]
},
'备注': {
'length': None,
'str_type': 'str',
'location': [(38, 'right', 0.2, 0.2, 0, (2, ), 'xmin', 'split')],
'fix_methods': [('prune_first_char', {'char_set': {';', ':', ':'}})]
},
}
INVOICE_CONST = {
ARG_KEY_KEY_LIST: INVOICE_KEY_LIST,
ARG_KEY_VALUE_DICT: INVOICE_VALUE_DICT
}
import re
import math
class Retriever:
def __init__(self, keys_list=[], values_dict={}):
self.keys_list = keys_list
self.values_dict = values_dict
self.find_keys_list = []
@staticmethod
def get_theta(x0, y0, x1, y1):
theta = math.atan((y0-y1)/(x1-x0))
return math.cos(theta), math.sin(theta)
@staticmethod
def rebuild_xy(x, y, cos, sin):
rebuild_x = x * cos - y * sin
rebuild_y = y * cos + x * sin
return rebuild_x, rebuild_y
def rebuild_coord(self, coord_tuple, cos, sin):
rebuild_list = []
for idx in range(0, len(coord_tuple), 2):
rebuild_list.extend(self.rebuild_xy(coord_tuple[idx], coord_tuple[idx+1], cos, sin))
return rebuild_list
@staticmethod
def prune_no_cn(src_str):
fix_str = re.sub(r'[^\u4e00-\u9fa5]+', '', src_str)
return fix_str
@staticmethod
def prune_first_char(src_str, char_set):
if src_str[0] in char_set:
return src_str[1:]
return src_str
@staticmethod
def prune_amount(src_str):
fix_str = ''.join(filter(lambda i: i in [',', '.'] or str.isdigit(i), src_str))
return fix_str
@staticmethod
def replace_whole(src_str, replace_map):
fix_str = src_str.translate(str.maketrans(replace_map))
return fix_str
@staticmethod
def replace_last_char(src_str, char_set, target_char):
if src_str[-1] in char_set:
return src_str[:-1] + target_char
return src_str
# @staticmethod
# def prune_RMB(src_str):
# return src_str
@staticmethod
def choice_xmin(value_list, value_length):
value_list.sort(key=lambda x: x[1])
return value_list[0]
@staticmethod
def choice_xmax(value_list, value_length):
value_list.sort(key=lambda x: x[1], reverse=True)
return value_list[0]
@staticmethod
def choice_ymin(value_list, value_length):
value_list.sort(key=lambda x: x[2])
return value_list[0]
@staticmethod
def choice_ymax(value_list, value_length):
value_list.sort(key=lambda x: x[2], reverse=True)
return value_list[0]
@staticmethod
def choice_merge(value_list, value_length):
value_list.sort(key=lambda x: x[2])
merged_value_list = []
merged_idx_list = []
merged_x_list = []
merged_y_list = []
for text, x0, y0, x1, y1, idx_tuple in value_list:
merged_value_list.append(text)
merged_idx_list.extend(idx_tuple)
merged_x_list.append(x0)
merged_x_list.append(x1)
merged_y_list.append(y0)
merged_y_list.append(y1)
return (''.join(merged_value_list),
min(merged_x_list),
min(merged_y_list),
max(merged_x_list),
max(merged_y_list),
tuple(merged_idx_list))
@staticmethod
def choice_length(value_list, value_length):
value_list.sort(key=lambda x: len(x[0]) - value_length)
return
def value_direction_left(self, go_res, key_idx, top_or_left, bottom_or_right, offset, scope_tuple, choice_method,
if_startswith, length):
# 字段值查找方向:左侧
if self.find_keys_list[key_idx] is None:
return
_, _, find_key_str, suffix_key, key_x0, key_y0, key_x1, key_y1 = self.find_keys_list[key_idx]
for scope_key_idx in scope_tuple[:-1]:
if self.find_keys_list[scope_key_idx] is None:
continue
key_scope = self.find_keys_list[scope_key_idx][6] # left x1
break
else:
key_scope = None
if isinstance(if_startswith, str):
if isinstance(suffix_key, str):
# TODO suffix_key校验与修正
# TODO 目前只考虑了split的情况
return suffix_key, key_x0, key_y0, key_x1, key_y1, ()
height = key_y1 - key_y0
y_min = key_y0 - (top_or_left * height)
y_max = key_y1 + (bottom_or_right * height)
width = key_x1 - key_x0
x_max = key_x0 - (offset * width)
x_min = x_max - (width * scope_tuple[-1]) if key_scope is None else key_scope
all_find_value_list = []
for go_key_idx, ((x0, y0, _, _, x1, y1, _, _), text) in go_res.items():
cent_x = x0 + ((x1 - x0) / 2)
cent_y = y0 + ((y1 - y0) / 2)
# if go_key_idx == '98' and key_idx == 34:
# print(key_scope)
# print('-------------')
# print(cent_x)
# print(cent_y)
# print('-----------')
# print(key_x0)
# print(key_x1)
# print(key_y0)
# print(key_y1)
# print('-----------')
# print(x_min)
# print(x_max)
# print(y_min)
# print(y_max)
# print('===============')
if x_min < cent_x < x_max and y_min < cent_y < y_max:
all_find_value_list.append((text, x0, y0, x1, y1, (go_key_idx, )))
if len(all_find_value_list) == 0:
return
elif len(all_find_value_list) == 1:
return all_find_value_list[0]
else:
choice_value = getattr(self, 'choice_{0}'.format(choice_method))(all_find_value_list, length)
return choice_value
# if isinstance(value_type, str) and value_type in self.replace_map and isinstance(value, str):
# new_value = value.translate(str.maketrans(self.replace_map.get(value_type, {})))
# return new_value, coordinates
def value_direction_right(self, go_res, key_idx, top_or_left, bottom_or_right, offset, scope_tuple, choice_method,
if_startswith, length):
# 字段值查找方向:右侧
if self.find_keys_list[key_idx] is None:
return
_, _, find_key_str, suffix_key, key_x0_src, key_y0_src, key_x1_src, key_y1_src, key_x2_src, key_y2_src, key_x3_src, key_y3_src = self.find_keys_list[key_idx]
for scope_key_idx in scope_tuple[:-1]:
if self.find_keys_list[scope_key_idx] is None:
continue
key_scope_tuple = (self.find_keys_list[scope_key_idx][4], self.find_keys_list[scope_key_idx][5]) # right x0, y0
break
else:
key_scope_tuple = None
if isinstance(if_startswith, str):
if isinstance(suffix_key, str):
# TODO suffix_key校验与修正
# TODO 目前只考虑了split的情况
if isinstance(length, int):
if -3 < length - len(suffix_key) < 3:
return suffix_key, (key_x0_src, key_y0_src, key_x1_src, key_y1_src, key_x2_src, key_y2_src, key_x3_src, key_y3_src), ()
else:
return suffix_key, (key_x0_src, key_y0_src, key_x1_src, key_y1_src, key_x2_src, key_y2_src, key_x3_src, key_y3_src), ()
# 坐标系转换
cos, sin = self.get_theta(x0, y0, x1, y1)
key_x0, key_y0, key_x1, key_y1, key_x2, key_y2, key_x3, key_y3 = self.rebuild_coord((key_x0_src, key_y0_src, key_x1_src, key_y1_src, key_x2_src, key_y2_src, key_x3_src, key_y3_src), cos, sin)
height = key_y2 - key_y0
y_min = key_y0 - (top_or_left * height)
y_max = key_y2 + (bottom_or_right * height)
width = key_x2 - key_x0
x_min = key_x2 + (offset * width)
x_max = x_min + (width * scope_tuple[-1]) if key_scope_tuple is None else self.rebuild_xy(*key_scope_tuple, cos, sin)[0]
all_find_value_list = []
for go_key_idx, ((x0, y0, x1, y1, x2, y3, x3, y3), text) in go_res.items():
cent_x, cent_y = self.rebuild_xy(x0 + ((x2 - x0) / 2), y0 + ((y2 - y0) / 2), cos, sin)
# if go_key_idx == '98' and key_idx == 34:
# print(cent_x)
# print(cent_y)
# print('-----------')
# print(key_x0)
# print(key_x1)
# print(key_y0)
# print(key_y1)
# print('-----------')
# print(x_min)
# print(x_max)
# print(y_min)
# print(y_max)
if x_min < cent_x < x_max and y_min < cent_y < y_max:
all_find_value_list.append((text, x0, y0, x1, y1, x2, y2, x3, y3, (go_key_idx, )))
if len(all_find_value_list) == 0:
return
elif len(all_find_value_list) == 1:
return all_find_value_list[0]
else:
# TODO choice时的坐标转换?
choice_value = getattr(self, 'choice_{0}'.format(choice_method))(all_find_value_list, length)
return choice_value
# if isinstance(value_type, str) and value_type in self.replace_map and isinstance(value, str):
# new_value = value.translate(str.maketrans(self.replace_map.get(value_type, {})))
# return new_value, coordinates
@staticmethod
def splitext(base_str, key_str, x0, y0, x1, y1, x2, y2, x3, y3):
suffix_value = base_str[len(key_str):] # TODO 坐标切分
return key_str, suffix_value, x1, y1, x2, y2
# return prefix_key, suffix_value, new_x1
def search_keys(self, go_res):
find_keys_list = [None for _ in range(len(self.keys_list))]
rm_go_key_set = set()
done_key_idx_set = set()
for key_idx, key_tuple in enumerate(self.keys_list):
for str_idx, ((x0, y0, x1, y1, x2, y2, x3, y3), text) in go_res.items():
if len(text.strip()) == 0: # 去除空格
rm_go_key_set.add(str_idx)
continue
for key_str in key_tuple[:-1]:
if text == key_str: # 全值匹配
find_keys_list[key_idx] = (key_tuple[0], key_str, text, None, x0, y0, x1, y1, x2, y2, x3, y3)
done_key_idx_set.add(key_idx)
rm_go_key_set.add(str_idx)
break
else:
continue
break
for go_key in rm_go_key_set:
go_res.pop(go_key)
rm_go_key_set.clear()
for key_idx, key_tuple in enumerate(self.keys_list):
if key_idx in done_key_idx_set or not key_tuple[-1]:
continue
for str_idx, ((x0, y0, x1, y1, x2, y2, x3, y3), text) in go_res.items():
if text.startswith(key_tuple[0]): # 以key开头
prefix_key, suffix_value, new_x1, new_y1, new_x2, new_y2 = self.splitext(
text, key_tuple[0], x0, y0, x1, y1, x2, y2, x3, y3)
find_keys_list[key_idx] = (key_tuple[0], key_tuple[0], text, suffix_value,
x0, y0, new_x1, new_y1, new_x2, new_y2, x3, y3)
done_key_idx_set.add(key_idx)
rm_go_key_set.add(str_idx)
break
for go_key in rm_go_key_set:
go_res.pop(go_key)
rm_go_key_set.clear()
self.find_keys_list = find_keys_list
# for i in find_keys_list:
# print(i)
def search_values(self, go_res):
# idx, location, top, bottom, left, (idx, scope), choice, if_startswith
find_value_dict = dict()
rm_go_key_set = set()
for cn_key, search_dict in self.values_dict.items():
for key_idx, direction_str, top_or_left, bottom_or_right, offset, scope_tuple, choice_method, if_startswith in search_dict['location']:
value_tuple = getattr(self, 'value_direction_{0}'.format(direction_str))(
go_res,
key_idx,
top_or_left,
bottom_or_right,
offset,
scope_tuple,
choice_method,
if_startswith,
search_dict['length'],
)
if isinstance(value_tuple, tuple):
break
if isinstance(value_tuple, tuple):
fixed_str = value_tuple[0]
for fix_method, kwargs in search_dict.get('fix_methods', []):
fixed_str = getattr(self, fix_method)(fixed_str, **kwargs)
find_value_dict[cn_key] = fixed_str
else:
find_value_dict[cn_key] = ''
# TODO 坐标重构
if isinstance(value_tuple, tuple):
for go_key in value_tuple[-1]:
go_res.pop(go_key)
return find_value_dict
def extract_fields(self, go_res):
# 搜索关键词
self.search_keys(go_res)
res = self.search_values(go_res)
return res
import json
import os
import base64
import requests
import cv2
import time
import numpy as np
from PIL import Image, ImageDraw, ImageFont
base_dir = os.path.dirname(os.path.abspath(__file__))
img_dir = '/home/zwq/data/gcfp/valid/image'
draw_dir = os.path.join(base_dir, 'draw', 'valid')
sign_dir = os.path.join(base_dir, 'sign_res', 'valid')
go_dir = os.path.join(base_dir, 'go_res', 'valid')
font_path = os.path.join(base_dir, 'simhei.ttf')
font = ImageFont.truetype(font_path, 10, encoding="utf-8")
for image_name in os.listdir(img_dir):
print('start: {0}'.format(image_name))
base_image_name, _ = os.path.splitext(image_name)
image_path = os.path.join(img_dir, image_name)
output_path = os.path.join(draw_dir, image_name)
go_res_path = os.path.join(go_dir, '{0}.json'.format(base_image_name))
sign_res_path = os.path.join(sign_dir, '{0}.json'.format(base_image_name))
go_response = requests.post(url=r'http://139.196.149.46:9001/gen_ocr', files={'file': open(image_path, 'rb')})
go_res = go_response.json()['ocr_results']
# print(go_res)
with open(go_res_path, 'w') as fp:
json.dump(go_res, fp, ensure_ascii=False)
img = cv2.imread(image_path)
for coordinates, text in go_res.values():
# print(coordinates)
# print(text)
cv2.rectangle(img, (coordinates[0], coordinates[1]), (coordinates[4], coordinates[5]), (0, 255, 0), 2)
pil_img = Image.fromarray(img)
draw = ImageDraw.Draw(pil_img)
draw.text((coordinates[0], coordinates[1]), text, (255, 0, 0), font=font)
img = np.array(pil_img)
cv2.imwrite(output_path, img)
sign_response = requests.post(url=r'http://139.196.149.46:9001/signature_detect', files={'file': open(image_path, 'rb')})
signature_res = sign_response.json()
with open(sign_res_path, 'w') as fp:
json.dump(signature_res, fp, ensure_ascii=False)
# print(signature_res)
# start_time = time.time()
# res = retriever_individuals.get_target_fields(go_res, signature_res)
# print(res)
# end_time = time.time()
# print('time: {0}'.format(end_time - start_time))
# break
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!