parkcheolhee-lab

Chamfer Distance



    import numpy as np


    def chamfer_distance(P, Q, normalize=True):
        """
            >>> P
            array([[1, 2, 3],
                   [4, 5, 6]])
            
            >>> Q
            array([[ 7,  8,  9],
                   [10, 11, 12],
                   [13, 14, 15]])
            )
            
            >>> P[:, None, :] - Q[None, :, :]
            array([[[ -6,  -6,  -6],      P_0 - Q_0
                    [ -9,  -9,  -9],      P_0 - Q_1
                    [-12, -12, -12]],     P_0 - Q_2
    
                    [[ -3,  -3,  -3],     P_1 - Q_0
                     [ -6,  -6,  -6],     P_1 - Q_1
                     [ -9,  -9,  -9]]])   P_1 - Q_2 
    
            >>> norms
            array([[10.39230485, 15.58845727, 20.78460969],
                   [ 5.19615242, 10.39230485, 15.58845727]])
    
                 (    [P_0 - Q_0, P_0 - Q_1, P_0 - Q_2],   )
                 (    [P_1 - Q_0, P_1 - Q_1, P_1 - Q_2],   )
        """
        
        norms = np.linalg.norm(P[:, None, :] - Q[None, :, :], axis=2)
    
        P_to_Q = norms.min(axis=1)
        Q_to_P = norms.min(axis=0)
        
        if normalize:
            return P_to_Q.mean() + Q_to_P.mean()
            
        return P_to_Q + Q_to_P
    
    
    if __name__ == "__main__":
    
        np.random.seed(777)
        
        P = np.random.random((2, 3)).round(1)
        Q = np.random.random((5, 3)).round(1)
        
        d = chamfer_distance(P, Q)