LiDAR-Diffusion / lidm /eval /eval_utils.py
Hancy's picture
init
851751e
raw
history blame
4.14 kB
"""
@Author: Haoxi Ran
@Date: 01/03/2024
@Citation: Towards Realistic Scene Generation with LiDAR Diffusion Models
"""
import multiprocessing
from functools import partial
import numpy as np
from scipy.spatial.distance import jensenshannon
from tqdm import tqdm
from . import OUTPUT_TEMPLATE
from .metric_utils import compute_logits, compute_pairwise_cd, \
compute_pairwise_emd, pcd2bev_sum, compute_pairwise_cd_batch, pcd2bev_bin
from .fid_score import calculate_frechet_distance
def evaluate(reference, samples, metrics, data):
# perceptual
if 'frid' in metrics:
compute_frid(reference, samples, data)
if 'fsvd' in metrics:
compute_fsvd(reference, samples, data)
if 'fpvd' in metrics:
compute_fpvd(reference, samples, data)
# reconstruction
if 'cd' in metrics:
compute_cd(reference, samples)
if 'emd' in metrics:
compute_emd(reference, samples)
# statistical
if 'jsd' in metrics:
compute_jsd(reference, samples, data)
if 'mmd' in metrics:
compute_mmd(reference, samples, data)
def compute_cd(reference, samples):
"""
Calculate score of Chamfer Distance (CD)
"""
print('Evaluating (CD) ...')
results = []
for x, y in zip(reference, samples):
d = compute_pairwise_cd(x, y)
results.append(d)
score = sum(results) / len(results)
print(OUTPUT_TEMPLATE.format('CD ', score))
def compute_emd(reference, samples):
"""
Calculate score of Earth Mover's Distance (EMD)
"""
print('Evaluating (EMD) ...')
results = []
for x, y in zip(reference, samples):
d = compute_pairwise_emd(x, y)
results.append(d)
score = sum(results) / len(results)
print(OUTPUT_TEMPLATE.format('EMD ', score))
def compute_mmd(reference, samples, data, dist='cd', verbose=True):
"""
Calculate the score of Minimum Matching Distance (MMD)
"""
print('Evaluating (MMD) ...')
assert dist in ['cd', 'emd']
reference, samples = pcd2bev_bin(data, reference, samples)
compute_dist_func = compute_pairwise_cd_batch if dist == 'cd' else compute_pairwise_emd
results = []
for r in tqdm(reference, disable=not verbose):
dists = compute_dist_func(r, samples)
results.append(min(dists))
score = sum(results) / len(results)
print(OUTPUT_TEMPLATE.format('MMD ', score))
def compute_jsd(reference, samples, data):
"""
Calculate the score of Jensen-Shannon Divergence (JSD)
"""
print('Evaluating (JSD) ...')
reference, samples = pcd2bev_sum(data, reference, samples)
reference = (reference / np.sum(reference)).flatten()
samples = (samples / np.sum(samples)).flatten()
score = jensenshannon(reference, samples)
print(OUTPUT_TEMPLATE.format('JSD ', score))
def compute_fd(reference, samples):
mu1, mu2 = np.mean(reference, axis=0), np.mean(samples, axis=0)
sigma1, sigma2 = np.cov(reference, rowvar=False), np.cov(samples, rowvar=False)
distance = calculate_frechet_distance(mu1, sigma1, mu2, sigma2)
return distance
def compute_frid(reference, samples, data):
"""
Calculate the score of Fréchet Range Image Distance (FRID)
"""
print('Evaluating (FRID) ...')
gt_logits, samples_logits = compute_logits(data, 'range', reference, samples)
score = compute_fd(gt_logits, samples_logits)
print(OUTPUT_TEMPLATE.format('FRID', score))
def compute_fsvd(reference, samples, data):
"""
Calculate the score of Fréchet Sparse Volume Distance (FSVD)
"""
print('Evaluating (FSVD) ...')
gt_logits, samples_logits = compute_logits(data, 'voxel', reference, samples)
score = compute_fd(gt_logits, samples_logits)
print(OUTPUT_TEMPLATE.format('FSVD', score))
def compute_fpvd(reference, samples, data):
"""
Calculate the score of Fréchet Point-based Volume Distance (FPVD)
"""
print('Evaluating (FPVD) ...')
gt_logits, samples_logits = compute_logits(data, 'point_voxel', reference, samples)
score = compute_fd(gt_logits, samples_logits)
print(OUTPUT_TEMPLATE.format('FPVD', score))