/ pytlib / image / random_perturber.py
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