isr_interface.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import base64
  2. import json
  3. import os
  4. import time
  5. import sys
  6. import traceback
  7. os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
  8. sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../")
  9. from format_convert import _global
  10. import cv2
  11. import numpy as np
  12. from PIL import Image
  13. from format_convert.utils import log, get_md5_from_bytes, request_post, np2pil, bytes2np, pil2np
  14. from isr.post_process import get_seal_part, replace_seal_part
  15. from isr.model import get_tiny_inference_model, seal_model, seal_model_se
  16. from isr.pre_process import count_red_pixel, get_anchors, get_classes, get_colors
  17. from isr.utils import get_best_predict_size, pil_resize, letterbox_image, draw_boxes, adjust_boxes
  18. import tensorflow as tf
  19. from flask import Flask, request
  20. tf.compat.v1.disable_eager_execution()
  21. sess1 = tf.compat.v1.Session(graph=tf.Graph())
  22. sess2 = tf.compat.v1.Session(graph=tf.Graph())
  23. def remove_seal(image_np, model):
  24. # inference data
  25. image_seal = image_np
  26. h, w = image_seal.shape[:2]
  27. best_h, best_w = get_best_predict_size(image_seal)
  28. X = np.zeros((1, best_h, best_w, 3))
  29. # resize
  30. image_seal = pil_resize(image_seal, best_h, best_w)
  31. # cv2.imshow("resize", image_seal)
  32. X[0] = image_seal / 255
  33. # predict
  34. with sess2.as_default():
  35. with sess2.graph.as_default():
  36. pred = model.predict(X)
  37. pred = pred[0]*255.
  38. pred = pred.astype(np.uint8)
  39. pred = pil_resize(pred, h, w)
  40. # cv2.imshow("pred", pred)
  41. # cv2.waitKey(0)
  42. return pred
  43. def detect_seal(image_np, model):
  44. image_pil = np2pil(image_np)
  45. # 首先判断红色像素
  46. # if not count_red_pixel(image_np):
  47. # return image_np, [], []
  48. # create image input
  49. h, w = image_np.shape[:2]
  50. # best_h, best_w = get_best_predict_size(image_np, times=32, max_size=1280)
  51. best_h, best_w = 1024, 1024
  52. image_resize = letterbox_image(image_pil, tuple(reversed([best_h, best_w])))
  53. # cv2.imshow("letterbox_image", pil2np(image_resize))
  54. # cv2.waitKey(0)
  55. # image_resize = pil_resize(image_np, best_h, best_w)
  56. # image_resize = image_pil.resize((int(416), int(416)), Image.BICUBIC)
  57. image_resize = np.array(image_resize, dtype='float32')
  58. image_resize = image_resize.astype('float32') / 255.
  59. image_resize = np.expand_dims(image_resize, 0)
  60. # create image shape input
  61. image_shape = np.array([image_pil.size[1], image_pil.size[0]])
  62. image_shape = np.expand_dims(image_shape, 0)
  63. # inference data
  64. with sess1.as_default():
  65. with sess1.graph.as_default():
  66. try:
  67. out_boxes, out_scores, out_classes = model.predict([image_resize, image_shape],steps=1)
  68. except ValueError as e:
  69. # if '(0, 4)' in traceback.format_exc():
  70. # log("there is no seal!")
  71. # out_boxes, out_scores, out_classes = [], [], []
  72. # else:
  73. # traceback.print_exc()
  74. # raise e
  75. traceback.print_exc()
  76. out_boxes, out_scores, out_classes = [], [], []
  77. if not isinstance(out_boxes, list) and not isinstance(out_classes, list):
  78. out_boxes = out_boxes.astype(np.int32)
  79. out_classes = out_classes.astype(np.int32)
  80. boxes = adjust_boxes(image_pil, out_boxes)
  81. else:
  82. boxes = out_boxes
  83. # # draw
  84. # class_names = get_classes(os.path.abspath(os.path.dirname(__file__))+"/yolo_data/my_classes.txt")
  85. # colors = get_colors(len(class_names))
  86. # image_draw = draw_boxes(image_pil, out_boxes, out_classes, out_scores, class_names, colors)
  87. # image_draw = cv2.cvtColor(np.array(image_draw), cv2.COLOR_RGB2BGR)
  88. # cv2.namedWindow('detect', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
  89. # cv2.imshow("detect", image_draw)
  90. # cv2.waitKey(0)
  91. return image_np, boxes, out_classes
  92. def isr(data, isr_yolo_model, isr_model):
  93. log("into isr_interface isr")
  94. try:
  95. img_data = base64.b64decode(data)
  96. img_np = bytes2np(img_data)
  97. _img, boxes, classes = detect_seal(img_np, isr_yolo_model)
  98. if not boxes and not classes:
  99. return {"image": img_np}
  100. part_list = get_seal_part(_img, boxes, classes)
  101. new_part_list = []
  102. for part in part_list:
  103. part_remove = remove_seal(part, isr_model)
  104. new_part_list.append(part_remove)
  105. img_replace = replace_seal_part(img_np, new_part_list, boxes)
  106. return {"image": img_replace}
  107. except TimeoutError:
  108. return {"image": [-5]}
  109. except:
  110. traceback.print_exc()
  111. return {"image": [-1]}
  112. # 接口配置
  113. app = Flask(__name__)
  114. @app.route('/isr', methods=['POST'])
  115. def _isr():
  116. _global._init()
  117. _global.update({"port": globals().get("port")})
  118. start_time = time.time()
  119. log("into isr_interface _isr")
  120. try:
  121. if not request.form:
  122. log("isr no data!")
  123. return json.dumps({"text": str([-9]), "bbox": str([-9])})
  124. data = request.form.get("data")
  125. log("isr_interface get data time" + str(time.time()-start_time))
  126. img_data = base64.b64decode(data)
  127. img_np = bytes2np(img_data)
  128. _md5 = request.form.get("md5")
  129. _global.update({"md5": _md5})
  130. # 初始化模型
  131. isr_yolo_model = globals().get("global_isr_yolo_model")
  132. isr_model = globals().get("global_isr_model")
  133. if isr_model is None or isr_yolo_model is None:
  134. print("=========== init isr model ===========")
  135. isr_yolo_model, isr_model = IsrModels().get_model()
  136. globals().update({"global_isr_yolo_model": isr_yolo_model})
  137. globals().update({"global_isr_model": isr_model})
  138. # 检测印章
  139. _img, boxes, classes = detect_seal(img_np, isr_yolo_model)
  140. # 检测不到,直接返回
  141. if not boxes and not classes:
  142. log("no seal detected!")
  143. return json.dumps({"image": [1]})
  144. else:
  145. log("there is " + str(len(boxes)) + " seals")
  146. # 截取
  147. part_list = get_seal_part(_img, boxes, classes)
  148. # 去除印章
  149. new_part_list = []
  150. for part in part_list:
  151. part_remove = remove_seal(part, isr_model)
  152. new_part_list.append(part_remove)
  153. # 替换
  154. img_replace = replace_seal_part(img_np, new_part_list, boxes)
  155. # numpy转为可序列化的string
  156. success, img_encode = cv2.imencode(".jpg", img_replace)
  157. # numpy -> bytes
  158. img_bytes = img_encode.tobytes()
  159. # bytes -> base64 bytes
  160. img_base64 = base64.b64encode(img_bytes)
  161. # base64 bytes -> string (utf-8)
  162. base64_string = img_base64.decode('utf-8')
  163. return json.dumps({"image": base64_string})
  164. except TimeoutError:
  165. return json.dumps({"image": [-5]})
  166. except:
  167. traceback.print_exc()
  168. return json.dumps({"image": [-1]})
  169. finally:
  170. log("isr interface finish time " + str(time.time()-start_time))
  171. class IsrModels:
  172. def __init__(self):
  173. # python文件所在目录
  174. _dir = os.path.abspath(os.path.dirname(__file__))
  175. # detect
  176. model_path = _dir + "/models/seal_detect_yolo.h5"
  177. anchors = get_anchors(_dir + "/yolo_data/my_anchors.txt")
  178. class_names = get_classes(_dir + "/yolo_data/my_classes.txt")
  179. colors = get_colors(len(class_names))
  180. with sess1.as_default():
  181. with sess1.graph.as_default():
  182. self.isr_yolo_model = get_tiny_inference_model(anchors, len(class_names), weights_path=model_path)
  183. self.isr_yolo_model.load_weights(model_path)
  184. # remove
  185. model_path = _dir + "/models/seal_remove_unet.h5"
  186. with sess2.as_default():
  187. with sess2.graph.as_default():
  188. self.isr_model = seal_model_se(input_shape=(None, None, 3),
  189. output_shape=(None, None, 3))
  190. self.isr_model.load_weights(model_path)
  191. def get_model(self):
  192. return [self.isr_yolo_model, self.isr_model]
  193. def test_isr_model(from_remote=False):
  194. file_path = "C:/Users/Administrator/Desktop/test_image/error10.jpg"
  195. with open(file_path, "rb") as f:
  196. file_bytes = f.read()
  197. file_base64 = base64.b64encode(file_bytes)
  198. _md5 = get_md5_from_bytes(file_bytes)[0]
  199. _global._init()
  200. _global.update({"port": 15010, "md5": _md5})
  201. if from_remote:
  202. file_json = {"data": file_base64, "md5": _md5}
  203. # _url = "http://192.168.2.102:17000/ocr"
  204. _url = "http://127.0.0.1:17000/ocr"
  205. print(json.loads(request_post(_url, file_json)))
  206. else:
  207. isr_yolo_model, isr_model = IsrModels().get_model()
  208. result = isr(file_base64, isr_yolo_model, isr_model)
  209. # print(result)
  210. if type(result.get("image")) == list:
  211. print(result)
  212. else:
  213. img = result.get("image")
  214. print(img.shape)
  215. cv2.namedWindow('img', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
  216. cv2.imshow("img", img)
  217. cv2.waitKey(0)
  218. # print(result)
  219. if __name__ == "__main__":
  220. test_isr_model()