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
Beispiel #4
0
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
Beispiel #5
0
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