random_perturber.py
1 from __future__ import division 2 from builtins import object 3 from past.utils import old_div 4 from utils.dict_utils import get_deep 5 from image.affine import Affine 6 from image.box import Box 7 from image.frame import Frame 8 import random 9 import numpy as np 10 import copy 11 12 # class for generating random affine transformations on boxes and images 13 class RandomPerturber(object): 14 15 @staticmethod 16 def generate_random_affine(center,edges,params): 17 affine = Affine() 18 19 # translate to center coordinates 20 affine.append(Affine.translation(-center)) 21 22 translate = get_deep(params,'translation_range',[-0.1,0.1]) 23 tx = random.random()*(translate[1]-translate[0])+translate[0] 24 ty = random.random()*(translate[1]-translate[0])+translate[0] 25 translation_range = np.array([tx,ty])*(-edges) 26 affine.append(Affine.translation(translation_range)) 27 28 scale = get_deep(params,'scaling_range',[0.9,1.4]) 29 scale = random.random()*(scale[1]-scale[0])+scale[0] 30 scaling_range = np.array([scale,scale]) 31 affine.append(Affine.scaling(scaling_range)) 32 33 # translate back 34 affine.append(Affine.translation(center)) 35 return affine 36 37 # scale and translation 38 @staticmethod 39 def perturb_crop_box(crop_box,params): 40 rand_affine = RandomPerturber.generate_random_affine(crop_box.center(),crop_box.edges(),params) 41 transformed_box = rand_affine.apply_to_box(crop_box) 42 return transformed_box 43 44 # scale, translation, (and rotation, TODO) 45 # returns a new frame 46 @staticmethod 47 def perturb_frame(frame,params): 48 dims = frame.image.get_hw() 49 rand_affine = RandomPerturber.generate_random_affine(old_div(dims,2),dims,params) 50 perturbed_frame = Frame(frame.image_path) 51 perturbed_frame.image = rand_affine.apply_to_image(frame.image,dims) 52 if frame.calib_mat is not None: 53 perturbed_frame.calib_mat = rand_affine.apply_to_matrix(frame.calib_mat) 54 for i,obj in enumerate(frame.objects): 55 # filter out completely out of bound objects 56 perturbed_obj_box = rand_affine.apply_to_box(obj.box) 57 perturbed_polygons = rand_affine.apply_to_polygons(obj.polygons) 58 if Box.intersection(perturbed_obj_box,perturbed_frame.image.get_bounding_box()) is not None: 59 obj_copy = copy.deepcopy(obj) 60 obj_copy.box = perturbed_obj_box 61 obj_copy.polygons = perturbed_polygons 62 perturbed_frame.objects.append(obj_copy) 63 return perturbed_frame 64