AiImageObject.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import logging
  2. import os
  3. import PIL.Image as Image
  4. from AnsjerPush.Config.aiConfig import LABEL_DICT, AI_IDENTIFICATION_TAGS_DICT
  5. class ImageProcessingObject:
  6. # 图片加工类
  7. def __init__(self, image_dir_path, image_size, image_row):
  8. self.image_dir_path = image_dir_path
  9. self.image_size = image_size
  10. self.image_row = image_row
  11. self.image_info_dict = {}
  12. def merge_images(self):
  13. """
  14. 合并图片
  15. """
  16. # 获取图片集地址下的所有图片名称
  17. image_full_path_list = self.get_image_full_path_list(self.image_dir_path)
  18. image_full_path_list.sort()
  19. image_save_path = r'{}.jpg'.format(self.image_dir_path) # 图片转换后的地址
  20. # 计算合成图片后的图片行数
  21. if len(image_full_path_list) % self.image_row == 0:
  22. image_row_num = len(image_full_path_list) // self.image_row
  23. else:
  24. image_row_num = len(image_full_path_list) // self.image_row + 1
  25. x_list = []
  26. y_list = []
  27. for img_file in image_full_path_list:
  28. img_x, img_y = self.get_new_img_xy(img_file, self.image_size)
  29. x_list.append(img_x)
  30. y_list.append(img_y)
  31. x_new = int(x_list[len(x_list) // 5 * 4])
  32. y_new = int(y_list[len(y_list) // 5 * 4])
  33. self.composite_images(self.image_row, self.image_size, image_row_num, image_full_path_list, image_save_path,
  34. x_new, y_new)
  35. self.image_info_dict = {'width': x_list[0], 'height': sum(y_list), 'num': len(y_list)}
  36. def get_image_full_path_list(self, image_dir_path):
  37. """
  38. 获取图片完整路径列表
  39. @param image_dir_path: 图片路径
  40. @return: image_full_path_list
  41. """
  42. file_name_list = os.listdir(image_dir_path)
  43. image_full_path_list = []
  44. for file_name_one in file_name_list:
  45. file_one_path = os.path.join(image_dir_path, file_name_one)
  46. if os.path.isfile(file_one_path):
  47. image_full_path_list.append(file_one_path)
  48. else:
  49. img_path_list = self.get_image_full_path_list(file_one_path)
  50. image_full_path_list.extend(img_path_list)
  51. return image_full_path_list
  52. @staticmethod
  53. def get_new_img_xy(img_file, image_size):
  54. """
  55. 获取图片宽高像素
  56. @param img_file: 图片文件
  57. @param image_size: 图片大小
  58. @return : x_s(宽像素), y_s(高像素)
  59. """
  60. im = Image.open(img_file)
  61. if image_size == 0: # 等于0时按照原比例
  62. (x_s, y_s) = im.size
  63. return x_s, y_s
  64. else:
  65. (x, y) = im.size
  66. lv = round(x / image_size, 2) + 0.01
  67. x_s = x // lv
  68. y_s = y // lv
  69. return x_s, y_s
  70. def composite_images(self, image_row, image_size, image_row_num, image_names, image_save_path, x_new, y_new):
  71. """
  72. 合成图片
  73. @param image_row: 图片行数(合成前)
  74. @param image_size: 图片大小
  75. @param image_row_num: 图片行数(合成后)
  76. @param image_names: 图片名字
  77. @param image_save_path: 图片保存路径
  78. @param x_new: 横向位置
  79. @param y_new: 纵向位置
  80. @return: None
  81. """
  82. to_image = Image.new('RGB', (image_row * x_new, image_row_num * y_new)) # 创建一个新图
  83. # 循环遍历,把每张图片按顺序粘贴到对应位置上
  84. total_num = 0
  85. for y in range(1, image_row_num + 1):
  86. for x in range(1, image_row + 1):
  87. from_image = self.resize_by_width(image_names[image_row * (y - 1) + x - 1], image_size)
  88. to_image.paste(from_image, ((x - 1) * x_new, (y - 1) * y_new))
  89. total_num += 1
  90. if total_num == len(image_names):
  91. break
  92. to_image.save(image_save_path) # 保存新图
  93. @staticmethod
  94. def resize_by_width(infile, image_size):
  95. """按照宽度进行所需比例缩放"""
  96. im = Image.open(infile)
  97. if image_size != 0:
  98. (x, y) = im.size
  99. lv = round(x / image_size, 2) + 0.01
  100. x_s = int(x // lv)
  101. y_s = int(y // lv)
  102. print("x_s", x_s, y_s)
  103. out = im.resize((x_s, y_s), Image.ANTIALIAS)
  104. return out
  105. else:
  106. (x_s, y_s) = im.size
  107. print("x_s", x_s, y_s)
  108. out = im.resize((x_s, y_s), Image.ANTIALIAS)
  109. return out
  110. def handle_rekognition_res(self, detect_group, rekognition_res):
  111. """
  112. 处理识别结果,匹配检测类型,并且返回标签坐标位置信息
  113. @param detect_group: 检测类型
  114. @param rekognition_res: 识别响应
  115. @return: label_dict
  116. """
  117. logger = logging.getLogger('info')
  118. labels = rekognition_res['Labels']
  119. logger.info('--------识别到的标签-------:{}'.format(labels))
  120. label_name = []
  121. label_list = []
  122. # 找出识别的所有标签
  123. for label in labels:
  124. label_name.append(label['Name'])
  125. for Parents in label['Parents']:
  126. label_name.append(Parents['Name'])
  127. logger.info('------标签名------:{}'.format(label_name))
  128. # 删除用户没有选择的ai识别类型, 并且得出最终识别结果
  129. user_detect_list = detect_group.split(',')
  130. user_detect_list = [i.strip() for i in user_detect_list]
  131. conform_label_list = []
  132. conform_detect_group = set()
  133. for key, label_type_val in LABEL_DICT.items():
  134. if key in user_detect_list:
  135. for label in label_type_val:
  136. if label in label_name:
  137. conform_detect_group.add(key)
  138. conform_label_list.append(label)
  139. # 找出标签边框线位置信息
  140. bounding_box_list = []
  141. for label in labels:
  142. if label['Name'] in conform_label_list:
  143. for label_instance in label['Instances']:
  144. bounding_box_list.append(label_instance['BoundingBox'])
  145. # 找出边框位置信息对应的单图位置并重新计算位置比
  146. merge_image_height = self.image_info_dict['height']
  147. single_height = merge_image_height // self.image_info_dict['num']
  148. new_bounding_box_dict = {
  149. 'file_0': [],
  150. 'file_1': [],
  151. 'file_2': []
  152. }
  153. for k, val in enumerate(bounding_box_list):
  154. bounding_box_top = merge_image_height * val['Top']
  155. # 找出当前边框属于哪张图片范围
  156. box_dict = {}
  157. for i in range(self.image_info_dict['num']):
  158. top_min = i * single_height
  159. top_max = (i + 1) * single_height
  160. if top_min <= bounding_box_top <= top_max:
  161. box_dict['Width'] = val['Width']
  162. box_dict['Height'] = merge_image_height * val['Height'] / single_height
  163. # 减去前i张图片的高度
  164. box_dict['Top'] = ((merge_image_height * val['Top']) - (i * single_height)) / single_height
  165. box_dict['Left'] = val['Left']
  166. new_bounding_box_dict['file_{i}'.format(i=i)].append(box_dict)
  167. # 组织返回数据
  168. if not conform_detect_group: # 没有识别到符合的标签
  169. event_type = ''
  170. label_list = []
  171. else:
  172. conform_detect_group = list(conform_detect_group)
  173. if len(conform_detect_group) > 1:
  174. conform_detect_group.sort()
  175. # 集成识别标签
  176. for label_key in conform_detect_group:
  177. label_list.append(AI_IDENTIFICATION_TAGS_DICT[label_key])
  178. event_type = ''.join(conform_detect_group) # 组合类型
  179. else:
  180. label_list.append(AI_IDENTIFICATION_TAGS_DICT[conform_detect_group[0]])
  181. event_type = conform_detect_group[0]
  182. logger.info('------conform_detect_group------ {}'.format(conform_detect_group))
  183. label_dict = {
  184. 'event_type': event_type,
  185. 'label_list': label_list,
  186. 'new_bounding_box_dict': new_bounding_box_dict
  187. }
  188. logger.info('------label_dict------ {}'.format(label_dict))
  189. return label_dict