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 rot_box(box,cterxy,imgwh,rot_angle,scale=1.0,correction=True): ''' Args: box:边框坐标[xmin,ymin,xmax,ymax] cterxy:旋转中心点坐标 [cter_x,cter_y] imgwh:图片宽高[w,h] rot_angle:旋转角 scale:放缩尺度 correction: bool,修正旋转后的目标框为正常左上右下坐标 return: box:边框坐标[x1,y1,x2,y2,x3,y3,x4,y4],左上开始,逆时针 ''' result_box = [] xmin,ymin,xmax,ymax = box[0],box[1],box[2],box[3] complete_coords = [xmin,ymin,xmin,ymax,xmax,ymax,xmax,ymin] for i in range(int(len(complete_coords)/2)): rotx,roty = rot_xy(cterxy[0],cterxy[1],complete_coords[2*i],complete_coords[2*i+1],rot_angle,scale) result_box.append(rotx) result_box.append(roty) if correction: xmin = min(result_box[0:len(result_box):2]) xmax = max(result_box[0:len(result_box):2]) ymin = min(result_box[1:len(result_box):2]) ymax = max(result_box[1:len(result_box):2]) xmin_v = utils.confine(xmin,0,imgwh[0]-1) ymin_v = utils.confine(ymin,0,imgwh[1]-1) xmax_v = utils.confine(xmax,0,imgwh[0]-1) ymax_v = utils.confine(ymax,0,imgwh[1]-1) #使用阈值剔除边缘截断严重的目标 if utils.calc_iou([xmin,ymin,xmax,ymax],[xmin_v,ymin_v,xmax_v,ymax_v]) < 0.5: xmin_v,ymin_v,xmax_v,ymin_v=0,0,0,0 return [xmin_v,ymin_v,xmin_v,ymax_v,xmax_v,ymax_v,xmax_v,ymin_v] else: return complete_coords
def crop_xy(x, y, top_left_x, top_left_y, crop_w, crop_h): ''' 坐标平移变换 Args: x,y:待变换坐标 top_left_x,top_left_y:裁剪图像左上角坐标 crop_w,crop_h:裁剪部分图像宽高 return: crop_x,crop_y ''' crop_x = int(x - top_left_x) crop_y = int(y - top_left_y) crop_x = utils.confine(crop_x, 0, crop_w - 1) crop_y = utils.confine(crop_y, 0, crop_h - 1) return crop_x, crop_y
def tile_xy(x, y, top_left_x, top_left_y, tile_w, tile_h): ''' 坐标平移变换 Args: x,y:待变换坐标 top_left_x,top_left_y:裁剪图像左上角坐标 tile_w,tile_h:裁剪部分图像宽高 return: tile_x,tile_y ''' tile_x = int(x - top_left_x) tile_y = int(y - top_left_y) tile_x = utils.confine(tile_x, 0, tile_w - 1) tile_y = utils.confine(tile_y, 0, tile_h - 1) return tile_x, tile_y
def transform_box(box, transforms): '''目标框坐标转换 Args: box:目标框[xmin,ymin,xmax,ymax] 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_box:转换后目标框坐标[xmin,ymin,xmax,ymax] ''' transformed_box = box for operate in transforms: if [0, 0, 0, 0] == transformed_box: break if transformed_box[2] > operate['imgwh'][0] or transformed_box[ 3] > operate['imgwh'][1]: print(operate['opt']) print(operate['imgwh']) print(transformed_box) if 'resize' == operate['opt']: transformed_box = resize.resize_box(transformed_box, operate['fx'], operate['fy']) elif 'rotate' == operate['opt']: #box,cterxy,imgwh,rot_angle,scale=1.0,correction=True tmp_box = rotate.rot_box(transformed_box, operate['cterxy'], operate['imgwh'], operate['rot_angle'], operate['scale'], operate['correction']) imgw, imgh = operate['imgwh'][0], operate['imgwh'][1] transformed_box = [ utils.confine(tmp_box[0], 0, imgw - 1), utils.confine(tmp_box[1], 0, imgh - 1), utils.confine(tmp_box[4], 0, imgw - 1), utils.confine(tmp_box[5], 0, imgh - 1) ] elif 'crop' == operate['opt']: transformed_box = crop.crop_box( transformed_box, operate['top_left_x'], operate['top_left_y'], operate['crop_w'], operate['crop_h'], operate['iou_thr']) elif 'flip' == operate['opt']: transformed_box = flip.flip_box(transformed_box, operate['imgwh'][0], operate['imgwh'][1], operate['flip_type']) return transformed_box