File size: 3,374 Bytes
e2e21d0
 
 
a707cb2
08c9919
 
 
 
 
 
 
e2e21d0
08c9919
 
 
 
 
 
e2e21d0
08c9919
e2e21d0
08c9919
 
e2e21d0
08c9919
 
 
e2e21d0
08c9919
 
e2e21d0
08c9919
 
 
e2e21d0
08c9919
 
e2e21d0
08c9919
e2e21d0
08c9919
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a707cb2
 
08c9919
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import torch
from skimage.metrics import structural_similarity as ssim
from skimage.metrics import peak_signal_noise_ratio as psnr
import glob
import argparse
import cv2
import numpy as np
import argparse
from tripy import shoelace_formula
from pyntcloud import PyntCloud
from pyntcloud.distance import euclidean_distances

def evaluate_rendering(args):
    ssim_values = []
    psnr_values = []
    test_rendering_paths = sorted(glob.glob(f'{args.path}/*.png'))
    for test_rendering_path in test_rendering_paths:
        combined_image = cv2.imread(test_rendering_path)

        height, width = combined_image.shape[:2]

        input_image = combined_image[:height // 2, :]
        rendered_image = combined_image[height // 2:, :]

        # Calculate SSIM and PSNR
        ssim_value = ssim(input_image, rendered_image, multichannel=True)
        psnr_value = psnr(input_image, rendered_image)

        ssim_values.append(ssim_value)
        psnr_values.append(psnr_value)

    # Log or print the SSIM and PSNR values
    ssim_average = sum(ssim_values) / len(ssim_values)
    psnr_average = sum(psnr_values) / len(psnr_values)

    print(f'average_SSIM: {ssim_average:.4f}')
    print(f'average_PSNR: {psnr_average:.4f}')

    return

def calculate_iou(mesh1, mesh2):
    # Compute intersection area using Shoelace formula
    intersection_area = shoelace_formula(mesh1.intersection(mesh2))

    # Compute union area using Shoelace formula
    union_area = shoelace_formula(mesh1) + shoelace_formula(mesh2) - intersection_area

    # Calculate Intersection over Union (IoU)
    iou = intersection_area / union_area
    return iou

def calculate_chamfer_distance(mesh1, mesh2):
    # Compute Chamfer distance using Euclidean distances
    distances1 = euclidean_distances(mesh1.vertices, mesh2.vertices).min(axis=1)
    distances2 = euclidean_distances(mesh2.vertices, mesh1.vertices).min(axis=1)
    chamfer_distance = (distances1.mean() + distances2.mean()) / 2
    return chamfer_distance

def calculate_normal_consistency(mesh1, mesh2):
    # Compute normal consistency as the cosine similarity of normals
    cos_similarity = np.abs(np.sum(mesh1.normals * mesh2.normals, axis=1))
    normal_consistency = cos_similarity.mean()
    return normal_consistency

def evaluate_3D(args):
    # Load 3D meshes (replace these paths with your mesh files)
    mesh1 = PyntCloud.from_file('path_to_mesh1.ply')
    mesh2 = PyntCloud.from_file('path_to_mesh2.ply')

    # Calculate IoU
    iou = calculate_iou(mesh1, mesh2)
    print(f'IoU: {iou:.4f}')

    # Calculate Chamfer distance
    chamfer_distance = calculate_chamfer_distance(mesh1, mesh2)
    print(f'Chamfer Distance: {chamfer_distance:.4f}')

    # Calculate normal consistency
    normal_consistency = calculate_normal_consistency(mesh1, mesh2)
    print(f'Normal Consistency: {normal_consistency:.4f}')

    return

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='3D Visualization')
    # evaluation over the rendering or the 3D reconstruction
    parser.add_argument('--mode', type=str, help='mode: rendering or 3D')
    # rendering file path or meshes file path
    parser.add_argument('--path', type=str, help='path to the file')
    args = parser.parse_args()
    if args.mode == 'rendering':
        evaluate_rendering(args)
    elif args.mode == '3D':
        evaluate_3D(args)