Task.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. from hub import methods, Global
  2. import cv2
  3. import base64
  4. class Task(object):
  5. @classmethod
  6. def task002(cls, **params):
  7. """获取特征值接口"""
  8. run_at = methods.now_ts()
  9. try:
  10. # --- get face_features ---
  11. call_id = params.get('call_id')
  12. save_is = params.get('save_is')
  13. rdb = Global.get_redis_client()
  14. image_bytes = rdb.get_one(key=call_id)
  15. # --- 人脸裁剪逻辑 ---
  16. # methods.debug_log('Task.task002', f"m-24: {type(image_bytes)}")
  17. image_array = Global.scrfd_agent.image_bytes_to_image_array(image_bytes)
  18. # methods.debug_log('Task.task002', f"m-24: {type(image_array)}")
  19. # inference_result = Global.scrfd_agent.inference(image_array)
  20. inference_result = Global.scrfd_agent.inference_with_image_array(image_array)
  21. # --- save file ---
  22. if save_is:
  23. save_at = methods.now_string('%Y-%m%d-%H%M%S-%f')
  24. frame = Global.arcface_agent.image_bytes_to_image_array(image_bytes)
  25. face_file_path = f"/home/server/resources/vms-files/{save_at}-raw.jpg"
  26. cv2.imwrite(face_file_path, frame)
  27. else:
  28. face_file_path = ''
  29. # --- check ---
  30. if not inference_result:
  31. return dict(code=1, details=f"something is wrong.")
  32. # --- 歪脸矫正 ---
  33. face_image = inference_result[0].get('align_face')
  34. probability = 0.0
  35. # --- 提取人脸特征 ---
  36. face_features = Global.arcface_agent.get_face_features_normalization_by_image_array(face_image)
  37. # --- check ---
  38. if face_features is None:
  39. return dict(code=2, details=f"something is wrong.")
  40. # --- debug to close --- todo 存在歪脸矫正后,图像图像变模糊的问题
  41. # save_at = methods.now_string('%Y-%m%d-%H%M%S-%f')
  42. # face_file_path_x = f"/home/server/resources/vms-files/{save_at}-align.jpg"
  43. # cv2.imwrite(face_file_path_x, face_image)
  44. # --- 增加戴口罩人脸底库特征与图片 ---
  45. masked_face_image = Global.face_to_mask_face.add_mask_one(face_image)
  46. if masked_face_image is not None:
  47. face_features_2 = Global.arcface_agent.get_face_features_normalization_by_image_array(masked_face_image)
  48. else:
  49. face_features_2 = face_features
  50. masked_face_image = face_image
  51. # --- save file ---
  52. if save_is:
  53. save_at = methods.now_string('%Y-%m%d-%H%M%S-%f')
  54. face_file_path_2 = f"/home/server/resources/vms-files/{save_at}-masked.jpg"
  55. cv2.imwrite(face_file_path_2, masked_face_image)
  56. else:
  57. face_file_path_2 = ''
  58. # --- update call_id value ---
  59. rdb.set_one(key=call_id, data=(face_features, probability, face_file_path,
  60. face_features_2, probability, face_file_path_2), expire_time=600)
  61. return dict(code=0, details=f"congratulations. | use time {methods.now_ts() - run_at}s")
  62. except Exception as exception:
  63. methods.debug_log('Task.task002', f"m-76: exception | {exception}")
  64. methods.debug_log('Task.task002', f"m-76: traceback | {methods.trace_log()}")
  65. return dict(code=-1, details=f"{methods.trace_log()}")
  66. @classmethod
  67. def task003(cls, **params):
  68. """
  69. 支持8301接口
  70. """
  71. run_at = methods.now_ts()
  72. try:
  73. # --- get data ---
  74. call_id = params.get('call_id')
  75. rdb = Global.get_redis_client()
  76. input_data = rdb.get_one(key=call_id)
  77. # --- 人脸裁剪逻辑 ---
  78. image_array = Global.scrfd_agent.image_bytes_to_image_array(input_data.get('image_bytes'))
  79. inference_result = Global.scrfd_agent.inference_with_image_array(image_array)
  80. # --- 歪脸矫正 ---
  81. face_image = inference_result[0].get('align_face')
  82. # --- 提取人脸特征 ---
  83. face_features = Global.arcface_agent.get_face_features_normalization_by_image_array(face_image)
  84. # methods.debug_log('Task.task003', f"m-105: face_features | {face_features}")
  85. # --- fill face_type_name_dict ---
  86. """
  87. face_type_name_dict = {<type_uuid>: <name>}
  88. """
  89. face_type_name_dict = dict()
  90. for item in Global.mdb.get_all('FaceType'):
  91. uuid = str(item.get('_id'))
  92. face_type_name_dict[uuid] = item.get('name')
  93. # --- fill d5 ---
  94. d5 = dict() # {<face_uuid>: {info}}
  95. for item in Global.mdb.get_all('Face'):
  96. face_uuid = str(item.get('_id'))
  97. d5[face_uuid] = item.copy()
  98. # --- fill d2 ---
  99. """
  100. FaceLog: 陌生人访问日志表
  101. FaceLog.face_image_path: 抓拍人脸图像路径
  102. FaceLog.face_probability: 人脸概率
  103. FaceLog.base_face_uuid: 底库人脸id
  104. FaceLog.base_face_image_path: 底库人脸图片路径
  105. FaceLog.face_similarity: 对比相似度
  106. FaceLog.count: 条目计数
  107. """
  108. d2 = list()
  109. start_ts = methods.string_to_ts(f"{input_data.get('start_date_at')}", pattern='%Y-%m-%d %H:%M:%S')
  110. end_ts = methods.string_to_ts(f"{input_data.get('end_date_at')}", pattern='%Y-%m-%d %H:%M:%S') + 1
  111. items = list(Global.xdb.filter_by_time_range('FaceLog', start_ts, end_ts))
  112. for item in items:
  113. # --- check ---
  114. base_face_uuid = item.get('base_face_uuid')
  115. if base_face_uuid not in d5:
  116. continue
  117. # --- check ---
  118. # face = Global.mdb.get_one_by_id('Face', base_face_uuid)
  119. face = d5.get(base_face_uuid)
  120. face_features_1 = methods.pickle_loads(face.get('face_feature_info_list')[0].get('face_features'))
  121. if face_features_1 is None:
  122. continue
  123. # --- check ---
  124. dist = Global.arcface_agent.compare_faces_by_normalization(face_features, face_features_1)
  125. if dist < input_data.get('face_similarity'):
  126. continue
  127. # --- fill ---
  128. d4 = item, face, dist
  129. d2.append(d4)
  130. # --- fill d3 ---
  131. d3 = list()
  132. page = input_data.get('page')
  133. size = input_data.get('size')
  134. for item, face, dist in d2[(page - 1) * size: page * size]:
  135. # --- fill d1 --- todo 返回数据 -> 抓拍照片、检索照片、相似度
  136. d1 = {
  137. 'face_uuid': item.get('base_face_uuid'),
  138. 'face_name': face.get('face_name'),
  139. 'record_at': methods.string_to_ts(item.get('time'), pattern='%Y-%m-%dT%H:%M:%S.%fZ'),
  140. 'snap_face_image_b64': str(), # 抓拍照片
  141. 'base_face_image_b64': str(), # 对比照片
  142. 'face_type_name_list': list(), # 类别名称
  143. 'face_similarity': dist, # 相似度
  144. }
  145. # methods.debug_log('actions.action_8201', f"m-86: d1 is {d1}")
  146. # --- fill snap_face_image_b64 ---
  147. file_path = item.get('face_image_path')
  148. if file_path and methods.is_file(file_path):
  149. frame = cv2.imread(file_path)
  150. if frame is not None:
  151. _, image = cv2.imencode('.jpg', frame)
  152. base64_data = base64.b64encode(image) # byte to b64 byte
  153. s = base64_data.decode() # byte to str
  154. d1['snap_face_image_b64'] = f'data:image/jpeg;base64,{s}'
  155. # --- fill base_face_image_b64 ---
  156. # file_path = item.get('base_face_image_path')
  157. # if file_path and methods.is_file(file_path):
  158. # frame = cv2.imread(file_path)
  159. # if frame is not None:
  160. # _, image = cv2.imencode('.jpg', frame)
  161. # base64_data = base64.b64encode(image) # byte to b64 byte
  162. # s = base64_data.decode() # byte to str
  163. # d1['base_face_image_b64'] = f'data:image/jpeg;base64,{s}'
  164. # --- fill base_face_image_b64 ---
  165. frame = Global.arcface_agent.image_bytes_to_image_array(input_data.get('image_bytes'))
  166. if frame is not None:
  167. _, image = cv2.imencode('.jpg', frame)
  168. base64_data = base64.b64encode(image) # byte to b64 byte
  169. s = base64_data.decode() # byte to str
  170. d1['base_face_image_b64'] = f'data:image/jpeg;base64,{s}'
  171. # --- fill face_type_name_list ---
  172. face_type_uuid_list = face.get('face_type_uuid_list')
  173. if face_type_uuid_list:
  174. d1['face_type_name_list'] = [face_type_name_dict.get(i)
  175. for i in face_type_uuid_list if face_type_name_dict.get(i)]
  176. # --- append d1 ---
  177. d3.append(d1)
  178. # --- update call_id value ---
  179. rdb.set_one(key=call_id, data=(d3, len(d2)), expire_time=600)
  180. return dict(code=0, details=f"congratulations. | use time {methods.now_ts() - run_at}s")
  181. except Exception as exception:
  182. methods.debug_log('Task.task003', f"m-76: exception | {exception}")
  183. methods.debug_log('Task.task003', f"m-76: traceback | {methods.trace_log()}")
  184. return dict(code=-1, details=f"{methods.trace_log()}")