def crop_xml(crop_img_name, xml_tree, top_left_x, top_left_y, crop_w, crop_h, iou_thr=0.5): '''xml目标框裁剪变换 Args: crop_img_name:裁剪图片命名 xml_tree:待crop的xml ET.parse() top_left_x,top_left_y: 裁剪图像左上角坐标 crop_w,crop_h: 裁剪图像宽高 iou_thr: iou阈值 return: createdxml : 创建的xml CreateXML对象 ''' root = xml_tree.getroot() size = root.find('size') depth = int(size.find('depth').text) createdxml = CreateXML(crop_img_name, int(crop_w), int(crop_h), depth) for obj in root.iter('object'): obj_name = obj.find('name').text xml_box = obj.find('bndbox') xmin = float(xml_box.find('xmin').text) ymin = float(xml_box.find('ymin').text) xmax = float(xml_box.find('xmax').text) ymax = float(xml_box.find('ymax').text) box = crop_box([xmin, ymin, xmax, ymax], top_left_x, top_left_y, crop_w, crop_h, iou_thr) if (box[0] >= box[2]) or (box[1] >= box[3]): continue createdxml.add_object_node(obj_name, box[0], box[1], box[2], box[3]) return createdxml
def rot_xml(rot_img_name,xml_tree,cterxy,rot_angle,scale=1.0,correction=True): ''' 旋转xml文件 Args: xml_tree: 待旋转xml ET.parse() cterxy: 旋转中心坐标[cter_x,cter_y] rot_img_name: 旋转后图片保存名字 rot_angle:旋转角度 scale:放缩尺度 correction: bool,修正旋转后的目标框为正常左上右下坐标 return: createdxml : 创建的xml CreateXML对象 ''' root = xml_tree.getroot() size = root.find('size') imgw,imgh,depth = int(size.find('width').text),int(size.find('height').text),int(size.find('depth').text) createdxml = CreateXML(rot_img_name,imgw,imgh,depth) for obj in root.iter('object'): obj_name = obj.find('name').text xml_box = obj.find('bndbox') xmin = int(xml_box.find('xmin').text) ymin = int(xml_box.find('ymin').text) xmax = int(xml_box.find('xmax').text) ymax = int(xml_box.find('ymax').text) #边框坐标[x1,y1,x2,y2,x3,y3,x4,y4],左上开始,逆时针 box=rot_box([xmin,ymin,xmax,ymax],cterxy,[imgw,imgh],rot_angle,scale,correction) rxmin,rymin,rxmax,rymax = utils.confine(box[0],0,imgw-1),utils.confine(box[1],0,imgh-1),utils.confine(box[4],0,imgw-1),utils.confine(box[5],0,imgh-1) if (rxmin >= rxmax) or (rymin >= rymax): continue createdxml.add_object_node(obj_name,box[0],box[1],box[4],box[5]) return createdxml
def flip_xml(flip_img_name,xml_tree,flip_type): '''翻转xml Args: flip_img_name:翻转后图片保存名 xml_tree:待翻转的xml ET.parse() flip_type:翻转类型,1水平翻转,0垂直翻转,-1水平垂直翻转 return: createdxml : 创建的xml CreateXML对象 ''' root = xml_tree.getroot() size = root.find('size') imgw,imgh,depth = int(size.find('width').text),int(size.find('height').text),int(size.find('depth').text) createdxml = CreateXML(flip_img_name,int(imgw),int(imgh),depth) for obj in root.iter('object'): obj_name = obj.find('name').text xml_box = obj.find('bndbox') xmin = int(xml_box.find('xmin').text) ymin = int(xml_box.find('ymin').text) xmax = int(xml_box.find('xmax').text) ymax = int(xml_box.find('ymax').text) box = flip_box([xmin,ymin,xmax,ymax],imgw,imgh,flip_type) if (box[0] >= box[2]) or (box[1] >= box[3]): continue createdxml.add_object_node(obj_name,box[0],box[1],box[2],box[3]) return createdxml
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 resize_xml(resized_img_name, xml_tree, dsize=(0, 0), fx=1.0, fy=1.0): ''' xml目标框放缩变换 Args: resized_img_name: resize图片保存名 xml_tree: 待resize xml ET.parse() dsize:指定放缩大小(w,h) fx,fy:比例放缩 return: createdxml : 创建的xml CreateXML对象 ''' root = xml_tree.getroot() size = root.find('size') imgw, imgh, depth = int(size.find('width').text), int( size.find('height').text), int(size.find('depth').text) resize_imgw, resize_imgh = imgw, imgh print("原始尺寸:", imgw, imgh) if dsize == (0, 0): resize_imgw = int(imgw * fx) resize_imgh = int(imgh * fy) else: resize_imgw, resize_imgh = dsize print("缩放尺寸:", resize_imgw, resize_imgh) rsize_fx, resize_fy = resize_imgw / imgw, resize_imgh / imgh createdxml = CreateXML(resized_img_name, resize_imgw, resize_imgh, depth) for obj in root.iter('object'): obj_name = obj.find('name').text xml_box = obj.find('bndbox') xmin = int(xml_box.find('xmin').text) ymin = int(xml_box.find('ymin').text) xmax = int(xml_box.find('xmax').text) ymax = int(xml_box.find('ymax').text) box = resize_box([xmin, ymin, xmax, ymax], rsize_fx, resize_fy) if (box[0] >= box[2]) or (box[1] >= box[3]): continue createdxml.add_object_node(obj_name, box[0], box[1], box[2], box[3]) return createdxml
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