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 flip_img_xml_from_dir(imgs_dir,xmls_dir,imgs_save_dir,xmls_save_dir,img_suffix,name_suffix,\ flip_types,random_flip=False): '''翻转指定路径下所有图片和xml Args: imgs_dir,xmls_dir:待翻转图片和xml路径 imgs_save_dir,xmls_save_dir:图片和xml保存路径 img_suffix:图片可能的后缀名['.jpg','.png','.bmp',..] name_suffix: 处理完成的图片、xml的命名标识 flip_types: 每张图执行的翻转类型[type1,type2,...],翻转类型共三种,1水平翻转,0垂直翻转,-1水平垂直翻转 random_flip:是否随机选择翻转类型,与flip_type互斥 ''' for root,dirs,files in os.walk(xmls_dir): for xml_name in files: xml_file = os.path.join(xmls_dir,xml_name) #print(xml_file) 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) types = flip_types if random_flip: types = [random.randint(-1,1)] for tp in types: flip_img_name = xml_name.split('.')[0]+'_'+name_suffix+'_type'+str(tp)+'.'+img_file.split('.')[-1] imgflip,xmlflip = flip_img_xml(img,voc_xml.get_xml_tree(xml_file),flip_img_name,tp) cv2.imwrite(os.path.join(imgs_save_dir,flip_img_name),imgflip) xmlflip.save_xml(xmls_save_dir,flip_img_name.split('.')[0]+'.xml')
def resizeImg_xml_from_dir(imgs_dir, xmls_dir, imgs_save_dir, xmls_save_dir, img_suffix, name_suffix, dsize=(0, 0), fx=1.0, fy=1.0): ''' 放缩指定路径下的图片和xml Args: imgs_dir,xmls_dir: 待放缩图片、原始xml文件存储路径 imgs_save_dir,xmls_save_dir: 处理完成的图片、xml文件存储路径 img_suffix: 图片可能的后缀名['.jpg','.png','.bmp',..] name_suffix: 处理完成的图片、xml的命名标识 dsize: 指定放缩大小(w,h) fx,fy: 比例放缩 ''' for root, dirs, files in os.walk(xmls_dir): for xml_name in files: xml_file = os.path.join(xmls_dir, xml_name) #print(xml_file) 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 resize_imgw, resize_imgh = imgw, imgh if dsize == (0, 0): resize_imgw = imgw * fx resize_imgh = imgh * fy else: resize_imgw, resize_imgh = dsize resized_img_name = xml_name.split( '.')[0] + '_' + name_suffix + str(resize_imgw) + 'x' + str( resize_imgh) + '.' + img_file.split('.')[-1] imgResize, xmlResize = generate_resizeImg_xml( img, voc_xml.get_xml_tree(xml_file), resized_img_name, dsize, fx, fy) cv2.imwrite(os.path.join(imgs_save_dir, resized_img_name), imgResize) xmlResize.save_xml(xmls_save_dir, resized_img_name.split('.')[0] + '.xml')
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 crop_img_xml_from_dir(imgs_dir, xmls_dir, imgs_save_dir, xmls_save_dir, img_suffix, name_suffix, dsize, iou_thr): for root, dirs, files in os.walk(xmls_dir): print(root, dirs, files) for xml_name in files: xml_file = os.path.join(xmls_dir, xml_name) print('xml:', xml_file) #打开xml文档 dom = et.parse(xml_file) root = dom.getroot() for ele in root.findall("object"): for point in ele.findall("bndbox"): xmin = point.find("xmin").text ymax = point.find("ymax").text 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 print("img_file:", img_file) img = cv2.imread(img_file) imgh, imgw, n_channels = img.shape crop_imgw, crop_imgh = dsize crop_top_left_x, crop_top_left_y = int(xmin) - 100, int(ymax) - 100 croped_img_name = xml_name.split('.')[0] + '_' + name_suffix +\ str(crop_top_left_x) + '_' + str(crop_top_left_y) +\ '_wh' + str(crop_imgw) + 'x' + str(crop_imgh) +\ '.' + img_file.split('.')[-1] croped = crop_img_xml(img, voc_xml.get_xml_tree(xml_file), croped_img_name, crop_top_left_x, crop_top_left_y, crop_imgw, crop_imgh, iou_thr) imgcrop, xmlcrop = croped[0], croped[1] cv2.imwrite(os.path.join(imgs_save_dir, croped_img_name), imgcrop) xmlcrop.save_xml(xmls_save_dir, croped_img_name.split('.')[0] + '.xml')
def transform_img_xml(src_imgpath,src_xmlpath,transforms,img_save_name): '''按transforms中的转换操作变换img和xml Args: src_imgpath: 待变换的图片路径 src_xmlpath: xml标注文件路径 transforms:转换操作 img_save_name: 图片保存名 return: transformed_img:转换完成的图片 createdxml:转换生成的新标签 ''' src_img = cv2.imread(src_imgpath) src_xml = voc_xml.get_xml_tree(src_xmlpath) transformed_img,certain_transforms = mosaic.transform_img(src_img,transforms) imgh,imgw,n_channels = transformed_img.shape createdxml = CreateXML(img_save_name,imgw,imgh,n_channels) createdxml = mosaic.transform_xml(src_xml,createdxml,certain_transforms,0,0) return transformed_img,createdxml
def crop_img_xml_from_dir(imgs_dir,xmls_dir,imgs_save_dir,xmls_save_dir,img_suffix,name_suffix,\ crop_type='RANDOM_CROP',crop_n=1,dsize=(0,0),fw=1.0,fh=1.0,random_wh=False,iou_thr=0.5): '''随机裁剪指定路径下的图片和xml Args: imgs_dir,xmls_dir: 待放缩图片、原始xml文件存储路径 imgs_save_dir,xmls_save_dir: 处理完成的图片、xml文件存储路径 img_suffix: 图片可能的后缀名['.jpg','.png','.bmp',..] name_suffix: 处理完成的图片、xml的命名标识 crop_type:裁剪风格 ['RANDOM_CROP','CENTER_CROP','FIVE_CROP'] crop_n: 每原图生成裁剪图个数 dsize:指定crop宽高(w,h),与random_wh==True互斥生效 fw,fh: 当random_wh==False时为crop比例,否则为随机crop的宽高比例下限 random_wh:随机选定裁剪宽高 iou_thr: iou阈值 ''' for root, dirs, files in os.walk(xmls_dir): for xml_name in files: xml_file = os.path.join(xmls_dir, xml_name) #print(xml_file) 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 bboxes = readAnnotations(xml_file) # print("img: {}, box: {}".format(image_path, bboxes)) x1, y1, x2, y2 = [], [], [], [] for box in bboxes: x1.append(box[0]) y1.append(box[1]) x2.append(box[2]) y2.append(box[3]) x1.sort() y1.sort() x2.sort() y2.sort() # print(annotation_path,x1[0],y1[0],x2[-1],y2[-1]) if crop_type == 'CENTER_CROP': crop_n = 1 elif crop_type == 'FIVE_CROP': crop_n = 5 elif crop_type == 'TwentyFour_CROP': crop_n = 21 for i in range(crop_n): crop_imgw, crop_imgh = dsize if dsize == (0, 0) and not random_wh: crop_imgw = int(imgw * fw) crop_imgh = int(imgh * fh) elif random_wh: crop_imgw = int(imgw * (fw + random.random() * (1 - fw))) crop_imgh = int(imgh * (fh + random.random() * (1 - fh))) if crop_type == 'RANDOM_CROP': crop_top_left_x, crop_top_left_y = random.randint( x1[0], x2[-1] - crop_imgw - 1), random.randint( y1[0], y2[-1] - crop_imgh - 1) elif crop_type == 'CENTER_CROP': crop_top_left_x, crop_top_left_y = int( imgw / 2 - crop_imgw / 2), int(imgh / 2 - crop_imgh / 2) elif crop_type == 'FIVE_CROP': if i == 0: crop_top_left_x, crop_top_left_y = 0, 0 elif i == 1: crop_top_left_x, crop_top_left_y = imgw - crop_imgw - 1, 0 elif i == 2: crop_top_left_x, crop_top_left_y = 0, imgh - crop_imgh - 1 elif i == 3: crop_top_left_x, crop_top_left_y = imgw - crop_imgw - 1, imgh - crop_imgh - 1 else: crop_top_left_x, crop_top_left_y = int( imgw / 2 - crop_imgw / 2), int(imgh / 2 - crop_imgh / 2) elif crop_type == 'TwentyFour_CROP': if i == 0: crop_top_left_x, crop_top_left_y = 0, 0 elif i == 1: crop_top_left_x, crop_top_left_y = 0, 512 elif i == 2: crop_top_left_x, crop_top_left_y = 0, 1024 elif i == 3: crop_top_left_x, crop_top_left_y = 512, 0 elif i == 4: crop_top_left_x, crop_top_left_y = 512, 512 elif i == 5: crop_top_left_x, crop_top_left_y = 512, 1024 elif i == 6: crop_top_left_x, crop_top_left_y = 1024, 0 elif i == 7: crop_top_left_x, crop_top_left_y = 1024, 512 elif i == 8: crop_top_left_x, crop_top_left_y = 1024, 1024 elif i == 9: crop_top_left_x, crop_top_left_y = 1536, 0 elif i == 10: crop_top_left_x, crop_top_left_y = 1536, 512 elif i == 11: crop_top_left_x, crop_top_left_y = 1536, 1024 elif i == 12: crop_top_left_x, crop_top_left_y = 2560, 0 elif i == 13: crop_top_left_x, crop_top_left_y = 2560, 512 elif i == 14: crop_top_left_x, crop_top_left_y = 2560, 1024 elif i == 15: crop_top_left_x, crop_top_left_y = 3072, 0 elif i == 16: crop_top_left_x, crop_top_left_y = 3072, 512 elif i == 17: crop_top_left_x, crop_top_left_y = 3072, 1024 elif i == 18: crop_top_left_x, crop_top_left_y = 3584, 0 elif i == 19: crop_top_left_x, crop_top_left_y = 3584, 512 else: crop_top_left_x, crop_top_left_y = 3584, 1024 # elif i == 21: # crop_top_left_x,crop_top_left_y = 3764,0 # elif i == 22: # crop_top_left_x,crop_top_left_y = 3764,512 # else: # crop_top_left_x,crop_top_left_y = 3764,1024 # else: # crop_top_left_x,crop_top_left_y = int(imgw/2-crop_imgw/2),int(imgh/2-crop_imgh/2) else: print( 'crop type wrong! expect [RANDOM_CROP,CENTER_CROP,FIVE_CROP]' ) croped_img_name = xml_name.split('.')[0]+'_'+name_suffix +\ str(crop_top_left_x)+'_'+str(crop_top_left_y)+\ '_wh'+str(crop_imgw)+'x'+str(crop_imgh)+\ '.'+img_file.split('.')[-1] croped = crop_img_xml(img, voc_xml.get_xml_tree(xml_file), croped_img_name, crop_top_left_x, crop_top_left_y, crop_imgw, crop_imgh, iou_thr) imgcrop, xmlcrop = croped[0], croped[1] cv2.imwrite(os.path.join(imgs_save_dir, croped_img_name), imgcrop) xmlcrop.save_xml(xmls_save_dir, croped_img_name.split('.')[0] + '.xml')
def crop_img_xml_from_dir(imgs_dir,xmls_dir,imgs_save_dir,xmls_save_dir,img_suffix,name_suffix,\ crop_type='RANDOM_CROP',crop_n=1,dsize=(0,0),fw=1.0,fh=1.0,random_wh=False,iou_thr=0.5): '''随机裁剪指定路径下的图片和xml Args: imgs_dir,xmls_dir: 待放缩图片、原始xml文件存储路径 imgs_save_dir,xmls_save_dir: 处理完成的图片、xml文件存储路径 img_suffix: 图片可能的后缀名['.jpg','.png','.bmp',..] name_suffix: 处理完成的图片、xml的命名标识 crop_type:裁剪风格 ['RANDOM_CROP','CENTER_CROP','FIVE_CROP'] crop_n: 每原图生成裁剪图个数 dsize:指定crop宽高(w,h),与random_wh==True互斥生效 fw,fh: 当random_wh==False时为crop比例,否则为随机crop的宽高比例下限 random_wh:随机选定裁剪宽高 iou_thr: iou阈值 ''' for root, dirs, files in os.walk(xmls_dir): for xml_name in files: xml_file = os.path.join(xmls_dir, xml_name) #print(xml_file) 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 if crop_type == 'CENTER_CROP': crop_n = 1 elif crop_type == 'FIVE_CROP': crop_n = 5 for i in range(crop_n): crop_imgw, crop_imgh = dsize if dsize == (0, 0) and not random_wh: crop_imgw = int(imgw * fw) crop_imgh = int(imgh * fh) elif random_wh: crop_imgw = int(imgw * (fw + random.random() * (1 - fw))) crop_imgh = int(imgh * (fh + random.random() * (1 - fh))) if crop_type == 'RANDOM_CROP': crop_top_left_x, crop_top_left_y = random.randint( 0, imgw - crop_imgw - 1), random.randint( 0, imgh - crop_imgh - 1) elif crop_type == 'CENTER_CROP': crop_top_left_x, crop_top_left_y = int( imgw / 2 - crop_imgw / 2), int(imgh / 2 - crop_imgh / 2) elif crop_type == 'FIVE_CROP': if i == 0: crop_top_left_x, crop_top_left_y = 0, 0 elif i == 1: crop_top_left_x, crop_top_left_y = imgw - crop_imgw - 1, 0 elif i == 2: crop_top_left_x, crop_top_left_y = 0, imgh - crop_imgh - 1 elif i == 3: crop_top_left_x, crop_top_left_y = imgw - crop_imgw - 1, imgh - crop_imgh - 1 else: crop_top_left_x, crop_top_left_y = int( imgw / 2 - crop_imgw / 2), int(imgh / 2 - crop_imgh / 2) else: print( 'crop type wrong! expect [RANDOM_CROP,CENTER_CROP,FIVE_CROP]' ) croped_img_name = xml_name.split('.')[0]+'_'+name_suffix +\ str(crop_top_left_x)+'_'+str(crop_top_left_y)+\ '_wh'+str(crop_imgw)+'x'+str(crop_imgh)+\ '.'+img_file.split('.')[-1] croped = crop_img_xml(img, voc_xml.get_xml_tree(xml_file), croped_img_name, crop_top_left_x, crop_top_left_y, crop_imgw, crop_imgh, iou_thr) imgcrop, xmlcrop = croped[0], croped[1] cv2.imwrite(os.path.join(imgs_save_dir, croped_img_name), imgcrop) xmlcrop.save_xml(xmls_save_dir, croped_img_name.split('.')[0] + '.xml')
def tile_img_xml_from_dir( imgs_dir, xmls_dir, imgs_save_dir, xmls_save_dir, img_suffix, name_suffix, # tile_type='RANDOM_tile', # tile_n=1, dsize=(1024, 1024), stepSize=(1024, 1024), iou_thr=0.5): '''使用移动滑窗裁剪原始图片 Args: imgs_dir,xmls_dir: 图片、原始xml文件存储路径 imgs_save_dir,xmls_save_dir: 处理完成的图片、xml文件存储路径 img_suffix: 图片可能的后缀名['.jpg','.png','.bmp',..] name_suffix: 处理完成的图片、xml的命名标识 dsize:指定tile宽高(w,h) iou_thr: iou阈值 ''' winW, winH = dsize[0], dsize[1] for root, dirs, files in os.walk(xmls_dir): for xml_name in files: xml_file = os.path.join(xmls_dir, xml_name) print('xml:', xml_file) 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 print("img_file:", img_file) img = cv2.imread(img_file) # print(img) imgh, imgw, n_channels = img.shape #移动滑窗裁剪 for (tile_top_left_x, tile_top_left_y, window) in sliding_window(img, stepSize=stepSize, windowsSize=(winW, winH)): if window.shape[0] != winH or window.shape[1] != winW: continue # slice=img[y:y+winH,x:x+winW] tileed_img_name = xml_name.split('.')[0] + '_' + name_suffix +\ str(tile_top_left_x) + '_' + str(tile_top_left_y) +\ '_wh' + str(winW) + 'x' + str(winH) +\ '.' + img_file.split('.')[-1] tileed = tile_img_xml(img, voc_xml.get_xml_tree(xml_file), tileed_img_name, tile_top_left_x, tile_top_left_y, winW, winH, iou_thr) imgtile, xmltile = tileed[0], tileed[1] cv2.imwrite(os.path.join(imgs_save_dir, tileed_img_name), imgtile) xmltile.save_xml(xmls_save_dir, tileed_img_name.split('.')[0] + '.xml')