import logging import os import PIL.Image as Image from AnsjerPush.Config.aiConfig import LABEL_DICT, AI_IDENTIFICATION_TAGS_DICT # 图片加工类 class ImageProcessingObject: def __init__(self, image_dir_path, image_size, image_row): self.image_dir_path = image_dir_path self.image_size = image_size self.image_row = image_row self.image_info_dict = {} def merge_images(self): """ 合并图片 """ # 获取图片集地址下的所有图片名称 image_full_path_list = self.get_image_full_path_list(self.image_dir_path) image_full_path_list.sort() image_save_path = r'{}.jpg'.format(self.image_dir_path) # 图片转换后的地址 # 计算合成图片后的图片行数 if len(image_full_path_list) % self.image_row == 0: image_row_num = len(image_full_path_list) // self.image_row else: image_row_num = len(image_full_path_list) // self.image_row + 1 x_list = [] y_list = [] for img_file in image_full_path_list: img_x, img_y = self.get_new_img_xy(img_file, self.image_size) x_list.append(img_x) y_list.append(img_y) x_new = int(x_list[len(x_list) // 5 * 4]) y_new = int(y_list[len(y_list) // 5 * 4]) self.composite_images(self.image_row, self.image_size, image_row_num, image_full_path_list, image_save_path, x_new, y_new) self.image_info_dict = {'width': x_list[0], 'height': sum(y_list), 'num': len(y_list)} def get_image_full_path_list(self, image_dir_path): """ 获取图片完整路径列表 @param image_dir_path: 图片路径 @return: image_full_path_list """ file_name_list = os.listdir(image_dir_path) image_full_path_list = [] for file_name_one in file_name_list: file_one_path = os.path.join(image_dir_path, file_name_one) if os.path.isfile(file_one_path): image_full_path_list.append(file_one_path) else: img_path_list = self.get_image_full_path_list(file_one_path) image_full_path_list.extend(img_path_list) return image_full_path_list @staticmethod def get_new_img_xy(img_file, image_size): """ 获取图片宽高像素 @param img_file: 图片文件 @param image_size: 图片大小 @return : x_s(宽像素), y_s(高像素) """ im = Image.open(img_file) if image_size == 0: # 等于0时按照原比例 (x_s, y_s) = im.size return x_s, y_s else: (x, y) = im.size lv = round(x / image_size, 2) + 0.01 x_s = x // lv y_s = y // lv return x_s, y_s def composite_images(self, image_row, image_size, image_row_num, image_names, image_save_path, x_new, y_new): """ 合成图片 @param image_row: 图片行数(合成前) @param image_size: 图片大小 @param image_row_num: 图片行数(合成后) @param image_names: 图片名字 @param image_save_path: 图片保存路径 @param x_new: 横向位置 @param y_new: 纵向位置 @return: None """ to_image = Image.new('RGB', (image_row * x_new, image_row_num * y_new)) # 创建一个新图 # 循环遍历,把每张图片按顺序粘贴到对应位置上 total_num = 0 for y in range(1, image_row_num + 1): for x in range(1, image_row + 1): from_image = self.resize_by_width(image_names[image_row * (y - 1) + x - 1], image_size) to_image.paste(from_image, ((x - 1) * x_new, (y - 1) * y_new)) total_num += 1 if total_num == len(image_names): break to_image.save(image_save_path) # 保存新图 @staticmethod def resize_by_width(infile, image_size): """按照宽度进行所需比例缩放""" im = Image.open(infile) if image_size != 0: (x, y) = im.size lv = round(x / image_size, 2) + 0.01 x_s = int(x // lv) y_s = int(y // lv) print("x_s", x_s, y_s) out = im.resize((x_s, y_s), Image.ANTIALIAS) return out else: (x_s, y_s) = im.size print("x_s", x_s, y_s) out = im.resize((x_s, y_s), Image.ANTIALIAS) return out def handle_rekognition_res(self, detect_group, rekognition_res): """ 处理识别结果,匹配检测类型,并且返回标签坐标位置信息 @param detect_group: 检测类型 @param rekognition_res: 识别响应 @return: label_dict """ logger = logging.getLogger('info') labels = rekognition_res['Labels'] logger.info('--------识别到的标签-------:{}'.format(labels)) label_name = [] label_list = [] # 找出识别的所有标签 for label in labels: label_name.append(label['Name']) for Parents in label['Parents']: label_name.append(Parents['Name']) logger.info('------标签名------:{}'.format(label_name)) # 删除用户没有选择的ai识别类型, 并且得出最终识别结果 user_detect_list = detect_group.split(',') user_detect_list = [i.strip() for i in user_detect_list] conform_label_list = [] conform_detect_group = set() for key, label_type_val in LABEL_DICT.items(): if key in user_detect_list: for label in label_type_val: if label in label_name: conform_detect_group.add(key) conform_label_list.append(label) # 找出标签边框线位置信息 bounding_box_list = [] for label in labels: if label['Name'] in conform_label_list: for label_instance in label['Instances']: bounding_box_list.append(label_instance['BoundingBox']) # 找出边框位置信息对应的单图位置并重新计算位置比 merge_image_height = self.image_info_dict['height'] single_height = merge_image_height // self.image_info_dict['num'] new_bounding_box_dict = { 'file_0': [], 'file_1': [], 'file_2': [] } for k, val in enumerate(bounding_box_list): bounding_box_top = merge_image_height * val['Top'] # 找出当前边框属于哪张图片范围 box_dict = {} for i in range(self.image_info_dict['num']): top_min = i * single_height top_max = (i + 1) * single_height if top_min <= bounding_box_top <= top_max: box_dict['Width'] = val['Width'] box_dict['Height'] = merge_image_height * val['Height'] / single_height # 减去前i张图片的高度 box_dict['Top'] = ((merge_image_height * val['Top']) - (i * single_height)) / single_height box_dict['Left'] = val['Left'] new_bounding_box_dict['file_{i}'.format(i=i)].append(box_dict) # 组织返回数据 if not conform_detect_group: # 没有识别到符合的标签 event_type = '' label_list = [] else: conform_detect_group = list(conform_detect_group) if len(conform_detect_group) > 1: conform_detect_group.sort() # 集成识别标签 for label_key in conform_detect_group: label_list.append(AI_IDENTIFICATION_TAGS_DICT[label_key]) event_type = ''.join(conform_detect_group) # 组合类型 else: label_list.append(AI_IDENTIFICATION_TAGS_DICT[conform_detect_group[0]]) event_type = conform_detect_group[0] logger.info('------conform_detect_group------ {}'.format(conform_detect_group)) label_dict = { 'event_type': event_type, 'label_list': label_list, 'new_bounding_box_dict': new_bounding_box_dict } logger.info('------label_dict------ {}'.format(label_dict)) return label_dict