def generate_img_xml(img_save_name, imgw, imgh, part_imgw, part_imgh, transforms, imgs_dir, xmls_dir): '''生成拼接图和拼接xml Args: img_save_name: imgw,imgh:生成总图宽高 transforms:转换操作 imgs_dir:图源目录 xmls_dir:图源对应的xml目录 return: img:总图 createdxml:总图创建的xml,ET.parse() ''' createdxml = CreateXML(img_save_name, imgw, imgh, 3) img = np.zeros((imgh, imgw, 3), dtype=np.uint8) part_cols = int(imgw / part_imgw) part_rows = int(imgh / part_imgh) for row in range(part_rows): for col in range(part_cols): start_row = row * part_imgh start_col = col * part_imgw part_img_file = utils.randomChoiceIn(imgs_dir) part_img = cv2.imread(os.path.join(imgs_dir, part_img_file)) part_xml_file = os.path.join(xmls_dir, part_img_file.split('.')[0] + '.xml') part_xml_tree = voc_xml.get_xml_tree(part_xml_file) img, createdxml = mosaic_img_xml(img, part_img, createdxml, part_xml_tree, transforms, start_row, start_col) return img, createdxml
def rotImg_xml_centre_from_dirs(imgs_dir,bk_imgs_dir,xmls_dir,rot_img_save_dir,rot_xmls_save_dir,img_suffix, name_suffix,rot_angles,randomAngleRange=[0,360],random_num=1,randomRotation=False,scale=1.0,correction = True): ''' 旋转指定路径下的所有图片和xml,以每张图片中心点为旋转中心,并存储到指定路径 Args: imgs_dir,bk_imgs_dir,xmls_dir: 待旋转图片、背景图片、原始xml文件存储路径 rot_img_save_dir,rot_xmls_save_dir:旋转完成的图片、xml文件存储路径 img_suffix: 图片可能的后缀名['.jpg','.png','.bmp',..] name_suffix:旋转完成的图片、xml的命名后缀标识 rot_angles: 指定旋转角度[ang1,ang2,ang3,...] randomAngleRange: 随机旋转上下限角度[bottom_angle,top_angle] random_num: 随机旋转角度个数,randomRotation=True时生效 randomRotation: 使能随机旋转 scale: 放缩尺度 correction: bool,修正旋转后的目标框为正常左上右下坐标 ''' for root,dirs,files in os.walk(xmls_dir): for xml_name in files: xml_file = os.path.join(xmls_dir,xml_name) img_file = None for suffix in img_suffix: #print(os.path.join(imgs_dir,xml_name.split('.')[0]+suffix)) if os.path.exists(os.path.join(imgs_dir,xml_name.split('.')[0]+suffix)): img_file = os.path.join(imgs_dir,xml_name.split('.')[0]+suffix) break if img_file is None: print("there has no image for ",xml_name) continue img = cv2.imread(img_file) imgh,imgw,n_channels = img.shape rot_num = random_num if not randomRotation: rot_num = len(rot_angles) for i in range(rot_num): r_angle = 0 if randomRotation: r_angle = random.randint(randomAngleRange[0],randomAngleRange[1]) else: r_angle = rot_angles[i] bk_img = cv2.imread(os.path.join(bk_imgs_dir,utils.randomChoiceIn(bk_imgs_dir))) rot_img_name = xml_name.split('.')[0]+'_'+name_suffix+str(r_angle)+'.'+img_file.split('.')[-1] imgRotation,xmlRotation=generate_rotImg_xml(img,bk_img,voc_xml.get_xml_tree(xml_file),[int(imgw/2),int(imgh/2)],rot_img_name,r_angle,scale,correction) cv2.imwrite(os.path.join(rot_img_save_dir,rot_img_name),imgRotation) xmlRotation.save_xml(rot_xmls_save_dir,rot_img_name.split('.')[0]+'.xml')
def transform_img(src_img, transforms): '''图像变换 Args: src_img:源图片 transforms:转换操作[{'opt':'rotate','cterxy':[],'imgwh':[],'rot_angle':0,'randomRotation':False,\ 'randomAngleRange':[0,360],'scale':1.0,'correction':True,'bk_imgs_dir':'xxx'}, {'opt':'crop','crop_type':RANDOM_CROP,'dsize':(0,0),'top_left_x':0,'top_left_y':0,'fw':0.5,'fh':0.7,'random_wh':False ,'iou_thr':0.5}, {'opt':'flip','flip_type':-1,'random_flip':True,'imgwh':[]}, {'opt':'resize','fx':0.5,'fy':0.5,'dsize':(0,0),'imgwh':[]}] return: transformed_img:变换后的图片 certain_transforms:实际变换操作参数 ''' certain_transforms = copy.deepcopy(transforms) imgh, imgw, depth = src_img.shape imgwh = [imgw, imgh] transformed_img = src_img for operate in certain_transforms: operate['imgwh'] = imgwh #每一种操作的输入图片宽高 if 'rotate' == operate['opt']: bk_img = cv2.imread( os.path.join(operate['bk_imgs_dir'], utils.randomChoiceIn(operate['bk_imgs_dir']))) cterxy = [int(imgw / 2), int(imgh / 2)] rot_angle = operate['rot_angle'] if operate['randomRotation']: rot_angle = random.randint(operate['randomAngleRange'][0], operate['randomAngleRange'][1]) transformed_img = rotate.rot_img_and_padding( transformed_img, bk_img, cterxy, rot_angle, operate['scale']) operate['cterxy'] = cterxy operate['rot_angle'] = rot_angle elif 'resize' == operate['opt']: resize_imgw, resize_imgh = imgwh[0], imgwh[1] if (0, 0) == operate['dsize']: resize_imgw = imgw * operate['fx'] resize_imgh = imgh * operate['fy'] else: resize_imgw, resize_imgh = operate['dsize'] transformed_img = resize.resize_img(transformed_img, operate['dsize'], operate['fx'], operate['fy']) imgwh = [resize_imgw, resize_imgh] operate['fx'] = resize_imgw / operate['imgwh'][0] operate['fy'] = resize_imgh / operate['imgwh'][1] elif 'crop' == operate['opt']: crop_imgw, crop_imgh = operate['dsize'] if (0, 0) == operate['dsize'] and not operate['random_wh']: crop_imgw = int(operate['imgwh'][0] * operate['fw']) crop_imgh = int(operate['imgwh'][1] * operate['fh']) elif operate['random_wh']: crop_imgw = int(operate['imgwh'][0] * (operate['fw'] + random.random() * (1 - operate['fw']))) crop_imgh = int(operate['imgwh'][1] * (operate['fh'] + random.random() * (1 - operate['fh']))) if 'CENTER_CROP' == operate['crop_type']: top_left_x, top_left_y = int(operate['imgwh'][0] / 2 - crop_imgw / 2), int(operate['imgwh'][1] / 2 - crop_imgh / 2) elif 'RANDOM_CROP' == operate['crop_type']: top_left_x, top_left_y = random.randint( 0, operate['imgwh'][0] - crop_imgw - 1), random.randint( 0, operate['imgwh'][1] - crop_imgh - 1) else: top_left_x, top_left_y = operate['top_left_x'], operate[ 'top_left_y'] transformed_img = crop.crop_img(transformed_img, top_left_x, top_left_y, crop_imgw, crop_imgh) imgwh = [crop_imgw, crop_imgh] operate['top_left_x'], operate[ 'top_left_y'] = top_left_x, top_left_y operate['crop_w'], operate['crop_h'] = crop_imgw, crop_imgh elif 'flip' == operate['opt']: flip_type = operate['flip_type'] if operate['random_flip']: flip_type = random.randint(-1, 1) transformed_img = flip.flip_img(transformed_img, flip_type) operate['flip_type'] = flip_type return transformed_img, certain_transforms