예제 #1
0
def earth_mover(pcd1, pcd2, radius=1.0):
    assert pcd1.shape[1] == pcd2.shape[1]
    num_points = tf.cast(pcd1.shape[1], tf.float32)
    match = tf_approxmatch.approx_match(pcd1, pcd2)
    cost = tf_approxmatch.match_cost(pcd1, pcd2, match)
    cost = cost / radius
    return tf.reduce_mean(cost / num_points)
예제 #2
0
def get_emd_loss(pcd1, pcd2,radius):
    assert pcd1.shape[1] == pcd2.shape[1]
    num_points = tf.cast(pcd1.shape[1], tf.float32)
    match = tf_approxmatch.approx_match(pcd1, pcd2)
    cost = tf_approxmatch.match_cost(pcd1, pcd2, match)
    cost = cost/radius
    return tf.reduce_mean(cost / num_points)
예제 #3
0
    def _compute_loss(self, prediction_tensor, target_tensor, weights):
        """

        Args:
            prediction_tensor (float): A tensor of shape [batch_size, h, w, 3]
            target_tensor (float): A tensor of shape [batch_size, h, w, 3]
            weights (float): A tensor of shape [batch_size, h, w, 1]

        Returns:
            loss (float): Approximate Earth Mover's Distance
        """

        # Multiply by valid mask
        valid_prediction_tensor = prediction_tensor * weights
        valid_target_tensor = target_tensor * weights

        # Reshape to (batch_size, n_points, 3)
        batch_size = prediction_tensor.get_shape()[0]
        valid_prediction_points = tf.reshape(valid_prediction_tensor, (batch_size, -1, 3))
        valid_target_points = tf.reshape(valid_target_tensor, (batch_size, -1, 3))

        match = tf_approxmatch.approx_match(valid_prediction_points, valid_target_points)
        distances = tf_approxmatch.match_cost(
            valid_prediction_points, valid_target_points, match)
        emd_distance = tf.reduce_sum(distances) / tf.cast(batch_size, tf.float32)

        return emd_distance
예제 #4
0
def get_loss(pred, label, end_points):
    """ pred: BxNx3,
        label: BxNx3, """
    dists_forward,_,dists_backward,_ = tf_nndistance.nn_distance(pred, label)
    pc_loss = tf.reduce_mean(dists_forward+dists_backward)
    end_points['pcloss'] = pc_loss

    match = tf_approxmatch.approx_match(label, pred)
    loss = tf.reduce_mean(tf_approxmatch.match_cost(label, pred, match))
    tf.summary.scalar('loss', loss)
    return loss, end_points
예제 #5
0
    def test_emd_negative(self):
        """Test negative point cloud values for computing the approximate Earth Mover's Distance.
        """

        # Create test point clouds of shape [batch_size, n_points, 3]
        point_cloud_1 = [[[-2., 2., -2.]]]
        point_cloud_2 = [[[2., 0., 2.]]]

        tf_point_cloud_1 = tf.constant(point_cloud_1)
        tf_point_cloud_2 = tf.constant(point_cloud_2)

        match = tf_approxmatch.approx_match(tf_point_cloud_1, tf_point_cloud_2)
        distance = tf.reduce_mean(tf_approxmatch.match_cost(point_cloud_1, point_cloud_2, match))

        with tf.Session() as sess:
            match, distance = sess.run([match, distance])

        np.testing.assert_almost_equal(distance, 6.0, decimal=2)
예제 #6
0
    def test_emd(self):
        """Test for the approximate algorithm for computing the distance where loss
        should be zero.
        """

        # Create test point clouds of shape [batch_size, n_points, 3]
        point_cloud_1 = [[[1., 1., 1.], [2., 2., 2.], [3., 3., 3.]]]
        point_cloud_2 = [[[1., 1., 1.], [2., 2., 2.], [3., 3., 3.]]]

        tf_point_cloud_1 = tf.constant(point_cloud_1)
        tf_point_cloud_2 = tf.constant(point_cloud_2)

        match = tf_approxmatch.approx_match(tf_point_cloud_1, tf_point_cloud_2)
        distance = tf.reduce_mean(tf_approxmatch.match_cost(point_cloud_1, point_cloud_2, match))

        with tf.Session() as sess:
            distance = sess.run([distance])

        np.testing.assert_almost_equal(distance, 0)
예제 #7
0
    def test_emd_batch(self):
        """Tests batches for the approximate algorithm for computing the Earth Mover's Distance.
        """

        # Create test point clouds of shape [batch_size, n_points, 3]
        point_cloud_1 = [[[1., 1., 1.], [2., 2., 2.], [3., 3., 3.]],
                         [[1., 1., 1.], [2., 2., 2.], [3., 3., 3.]]]
        point_cloud_2 = [[[1., 0., 1.], [2., 0., 2.], [3., 0., 3.]],
                         [[4., 4., 4.], [2., 2., 2.], [3., 3., 3.]]]

        tf_point_cloud_1 = tf.constant(point_cloud_1)
        tf_point_cloud_2 = tf.constant(point_cloud_2)

        match = tf_approxmatch.approx_match(tf_point_cloud_1, tf_point_cloud_2)
        distance = tf_approxmatch.match_cost(point_cloud_1, point_cloud_2, match)

        with tf.Session() as sess:
            match, distance = sess.run([match, distance])

        np.testing.assert_almost_equal(distance, [6.0, 5.196152], decimal=2)
예제 #8
0
    def test_emd_2(self):
        """Test for the approximate algorithm for computing the Earth Mover's Distance to see
        if match selects closest point, and if the loss is reasonable.
        """

        # Create test point clouds of shape [batch_size, n_points, 3]
        point_cloud_1 = [[[1., 1., 1.], [2., 2., 2.], [3., 3., 3.]]]
        point_cloud_2 = [[[1., 0., 1.], [2., 0., 2.], [3., 0., 3.]]]

        tf_point_cloud_1 = tf.constant(point_cloud_1)
        tf_point_cloud_2 = tf.constant(point_cloud_2)

        match = tf_approxmatch.approx_match(tf_point_cloud_1, tf_point_cloud_2)
        distance = tf.reduce_mean(tf_approxmatch.match_cost(point_cloud_1, point_cloud_2, match))

        with tf.Session() as sess:
            match, distance = sess.run([match, distance])

        matched_indices = np.argmax(np.squeeze(match), axis=1)
        np.testing.assert_equal(matched_indices, [0, 1, 2])
        np.testing.assert_almost_equal(distance, 6.0, decimal=2)