def test_postprocess_with_nms(self): num_voxels = 10000 outputs = { standard_fields.DetectionResultFields.object_semantic_voxels: tf.random.uniform([num_voxels, 10], minval=-1.0, maxval=1.0, dtype=tf.float32), standard_fields.DetectionResultFields.instance_embedding_voxels: tf.random.uniform([num_voxels, 64], minval=-1.0, maxval=1.0, dtype=tf.float32) } postprocessor.postprocess( outputs=outputs, num_furthest_voxel_samples=200, sampler_score_vs_distance_coef=0.5, embedding_similarity_strategy='distance', apply_nms=True, nms_score_threshold=0.1) num_instances = outputs[standard_fields.DetectionResultFields .instance_segments_voxel_mask].shape[0] self.assertAllEqual( outputs[standard_fields.DetectionResultFields .instance_segments_voxel_mask].shape, np.array([num_instances, num_voxels])) self.assertAllEqual( outputs[standard_fields.DetectionResultFields.objects_class].shape, np.array([num_instances, 1])) self.assertAllEqual( outputs[standard_fields.DetectionResultFields.objects_score].shape, np.array([num_instances, 1]))
def postprocess(inputs, outputs, is_training, num_furthest_voxel_samples, sampler_score_vs_distance_coef, embedding_similarity_strategy, embedding_similarity_threshold, score_threshold, apply_nms, nms_iou_threshold): """Post-processor function. Args: inputs: A dictionary containing input tensors. outputs: A dictionary containing predicted tensors. is_training: If during training stage or not. num_furthest_voxel_samples: Number of voxels to be sampled using furthest voxel sampling in the postprocessor. sampler_score_vs_distance_coef: The coefficient that balances the weight between furthest voxel sampling and highest score sampling in the postprocessor. embedding_similarity_strategy: Embedding similarity strategy. embedding_similarity_threshold: Similarity threshold used to decide if two point embedding vectors belong to the same instance. score_threshold: Instance score threshold used throughout postprocessing. apply_nms: If True, it will apply non-maximum suppression to the final predictions. nms_iou_threshold: Intersection over union threshold used in non-maximum suppression. """ if not is_training: # Squeeze output voxel properties. for key in standard_fields.get_output_voxel_fields(): if key in outputs and outputs[key] is not None: outputs[key] = tf.squeeze(outputs[key], axis=0) # Squeeze output point properties. for key in standard_fields.get_output_point_fields(): if key in outputs and outputs[key] is not None: outputs[key] = tf.squeeze(outputs[key], axis=0) # Squeeze output object properties. for key in standard_fields.get_output_object_fields(): if key in outputs and outputs[key] is not None: outputs[key] = tf.squeeze(outputs[key], axis=0) # Mask the valid voxels mask_valid_voxels(inputs=inputs, outputs=outputs) # Mask the valid points mask_valid_points(inputs=inputs, outputs=outputs) # NMS postprocessor.postprocess( outputs=outputs, num_furthest_voxel_samples=num_furthest_voxel_samples, sampler_score_vs_distance_coef=sampler_score_vs_distance_coef, embedding_similarity_strategy=embedding_similarity_strategy, embedding_similarity_threshold=embedding_similarity_threshold, apply_nms=apply_nms, nms_score_threshold=score_threshold, nms_iou_threshold=nms_iou_threshold) # Add instance segment point masks at eval time if standard_fields.InputDataFields.points_to_voxel_mapping in inputs: instance_segments_point_mask = ( voxel_utils.sparse_voxel_grid_to_pointcloud( voxel_features=tf.expand_dims(tf.transpose( outputs[standard_fields.DetectionResultFields. instance_segments_voxel_mask]), axis=0), segment_ids=inputs[standard_fields.InputDataFields. points_to_voxel_mapping], num_valid_voxels=inputs[ standard_fields.InputDataFields.num_valid_voxels], num_valid_points=inputs[ standard_fields.InputDataFields.num_valid_points])) outputs[standard_fields.DetectionResultFields. instance_segments_point_mask] = tf.transpose( tf.squeeze(instance_segments_point_mask, axis=0))