def compute_xyz(depth_img, fx, fy, px, py, height, width): indices = util_.build_matrix_of_indices(height, width) z_e = depth_img x_e = (indices[..., 1] - px) * z_e / fx y_e = (indices[..., 0] - py) * z_e / fy xyz_img = np.stack([x_e, y_e, z_e], axis=-1) # Shape: [H x W x 3] return xyz_img
def compute_xyz(depth_img, camera_params): """ Compute ordered point cloud from depth image and camera parameters. If focal lengths fx,fy are stored in the camera_params dictionary, use that. Else, assume camera_params contains parameters used to generate synthetic data (e.g. fov, near, far, etc) @param depth_img: a [H x W] numpy array of depth values in meters @param camera_params: a dictionary with parameters of the camera used """ # Compute focal length from camera parameters if 'fx' in camera_params and 'fy' in camera_params: fx = camera_params['fx'] fy = camera_params['fy'] else: # simulated data aspect_ratio = camera_params['img_width'] / camera_params['img_height'] e = 1 / (np.tan(np.radians(camera_params['fov'] / 2.))) t = camera_params['near'] / e b = -t r = t * aspect_ratio l = -r alpha = camera_params['img_width'] / (r - l) # pixels per meter focal_length = camera_params[ 'near'] * alpha # focal length of virtual camera (frustum camera) fx = focal_length fy = focal_length if 'x_offset' in camera_params and 'y_offset' in camera_params: x_offset = camera_params['x_offset'] y_offset = camera_params['y_offset'] else: # simulated data x_offset = camera_params['img_width'] / 2 y_offset = camera_params['img_height'] / 2 indices = util_.build_matrix_of_indices(camera_params['img_height'], camera_params['img_width']) z_e = depth_img x_e = (indices[..., 1] - x_offset) * z_e / fx y_e = (indices[..., 0] - y_offset) * z_e / fy xyz_img = np.stack([x_e, y_e, z_e], axis=-1) # Shape: [H x W x 3] return xyz_img
def random_rotation(label): """ Randomly rotate mask @param label: a [H x W] numpy array of {0, 1} """ H, W = label.shape num_tries = 0 valid_transform = False while not valid_transform: if num_tries >= cfg.TRAIN.max_augmentation_tries: print('Rotate: Exhausted number of augmentation tries...') return label # Rotate about center of box pixel_indices = util_.build_matrix_of_indices(H, W) h_idx, w_idx = np.where(label) mean = np.mean(pixel_indices[h_idx, w_idx, :], axis=0) # Shape: [2]. y_center, x_center # Sample an angle applied_angle = np.random.uniform(-cfg.TRAIN.rotation_angle_max, cfg.TRAIN.rotation_angle_max) rotated_label = rotate(label, applied_angle, center=tuple(mean[::-1]), interpolation=cv2.INTER_NEAREST) # Make sure the mass is reasonable if (np.count_nonzero(rotated_label) / rotated_label.size > 0.001) and \ (np.count_nonzero(rotated_label) / rotated_label.size < 0.98): valid_transform = True num_tries += 1 return rotated_label
def random_ellipses(label): """ Randomly add/drop a few ellipses in the mask This is adapted from the DexNet 2.0 code. Their code: https://github.com/BerkeleyAutomation/gqcnn/blob/75040b552f6f7fb264c27d427b404756729b5e88/gqcnn/sgd_optimizer.py @param label: a [H x W] numpy array of {0, 1} """ H, W = label.shape num_tries = 0 valid_transform = False while not valid_transform: if num_tries >= cfg.TRAIN.max_augmentation_tries: print('Ellipse: Exhausted number of augmentation tries...') return label new_label = label.copy() # Sample number of ellipses to include/dropout num_ellipses = np.random.poisson(cfg.TRAIN.num_ellipses_mean) # Sample ellipse centers by sampling from Gaussian at object center pixel_indices = util_.build_matrix_of_indices(H, W) h_idx, w_idx = np.where(new_label) mu = np.mean(pixel_indices[h_idx, w_idx, :], axis=0) # Shape: [2]. y_center, x_center sigma = 2 * np.cov(pixel_indices[h_idx, w_idx, :].T) # Shape: [2 x 2] if np.any(np.isnan(mu)) or np.any(np.isnan(sigma)): print(mu, sigma, h_idx, w_idx) ellipse_centers = np.random.multivariate_normal( mu, sigma, size=num_ellipses) # Shape: [num_ellipses x 2] ellipse_centers = np.round(ellipse_centers).astype(int) # Sample ellipse radii and angles x_min, y_min, x_max, y_max = util_.mask_to_tight_box(new_label) scale_factor = max( x_max - x_min, y_max - y_min) * cfg.TRAIN.ellipse_size_percentage # Mean of gamma r.v. x_radii = np.random.gamma(cfg.TRAIN.ellipse_gamma_base_shape * scale_factor, cfg.TRAIN.ellipse_gamma_base_scale, size=num_ellipses) y_radii = np.random.gamma(cfg.TRAIN.ellipse_gamma_base_shape * scale_factor, cfg.TRAIN.ellipse_gamma_base_scale, size=num_ellipses) angles = np.random.randint(0, 360, size=num_ellipses) # Dropout ellipses for i in range(num_ellipses): center = ellipse_centers[i, :] x_radius = np.round(x_radii[i]).astype(int) y_radius = np.round(y_radii[i]).astype(int) angle = angles[i] # include or dropout the ellipse mask = np.zeros_like(new_label) mask = cv2.ellipse(mask, tuple(center[::-1]), (x_radius, y_radius), angle=angle, startAngle=0, endAngle=360, color=1, thickness=-1) if np.random.rand() < 0.5: new_label[mask == 1] = 0 # Drop out ellipse else: new_label[mask == 1] = 1 # Add ellipse # Make sure the mass is reasonable if (np.count_nonzero(new_label) / new_label.size > 0.001) and \ (np.count_nonzero(new_label) / new_label.size < 0.98): valid_transform = True num_tries += 1 return new_label