111 lines
3.3 KiB
Python
111 lines
3.3 KiB
Python
import glob
|
|
import os
|
|
|
|
import cv2
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
import scipy.stats as stats
|
|
from skimage.metrics import structural_similarity as ssim
|
|
from tqdm import tqdm
|
|
|
|
# use this: https://sketch.io
|
|
|
|
def calculate_rmse(imageA, imageB):
|
|
err = np.sum((imageA - imageB) ** 2)
|
|
err /= float(imageA.shape[0] * imageA.shape[1])
|
|
return np.sqrt(err)
|
|
|
|
def compare_images(ground_truth_path, sample_paths):
|
|
results = []
|
|
gt_image = cv2.imread(ground_truth_path, cv2.IMREAD_GRAYSCALE)
|
|
|
|
if gt_image is None:
|
|
raise ValueError("Ground truth image could not be read. Please check the file path.")
|
|
|
|
gt_image = gt_image.astype("float") / 255.0
|
|
|
|
for path in tqdm(sample_paths):
|
|
sample_image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
|
|
|
|
if sample_image is None:
|
|
print(f"WARNING: Sample image at path {path} could not be read. Skipping this image.")
|
|
continue
|
|
|
|
sample_image = sample_image.astype("float") / 255.0
|
|
|
|
rmse_value = calculate_rmse(gt_image, sample_image)
|
|
ssim_value, _ = ssim(gt_image, sample_image, full=True, data_range=1) # Corrected line
|
|
|
|
diff_mask = cv2.absdiff(gt_image, sample_image)
|
|
|
|
# plt.imshow(diff_mask * 255, cmap='gray')
|
|
# plt.title(f'Difference Mask for {os.path.basename(path)}\nRMSE: {rmse_value:.5f} - SSIM: {ssim_value:.5f}')
|
|
# plt.show()
|
|
|
|
results.append({
|
|
'path': path,
|
|
'rmse': rmse_value,
|
|
'ssim': ssim_value,
|
|
'diff_mask': diff_mask
|
|
})
|
|
|
|
return results
|
|
|
|
|
|
ground_truth = 'ground_truth.png'
|
|
sample_images = glob.glob("samples/*.png")
|
|
|
|
results = compare_images(ground_truth, sample_images)
|
|
|
|
for res in results:
|
|
print(f"Image: {res['path']} - RMSE: {res['rmse']} - SSIM: {res['ssim']}")
|
|
|
|
def calculate_confidence_interval(data, confidence_level=0.95):
|
|
mean = np.mean(data)
|
|
sem = stats.sem(data)
|
|
df = len(data) - 1
|
|
me = sem * stats.t.ppf((1 + confidence_level) / 2, df)
|
|
return mean - me, mean + me
|
|
|
|
rmse_values = [res['rmse'] for res in results]
|
|
ssim_values = [res['ssim'] for res in results]
|
|
|
|
rmse_mean = np.mean(rmse_values)
|
|
rmse_median = np.median(rmse_values)
|
|
rmse_stdev = np.std(rmse_values, ddof=1)
|
|
|
|
ssim_mean = np.mean(ssim_values)
|
|
ssim_median = np.median(ssim_values)
|
|
ssim_stdev = np.std(ssim_values, ddof=1)
|
|
|
|
rmse_ci = calculate_confidence_interval(rmse_values)
|
|
ssim_ci = calculate_confidence_interval(ssim_values)
|
|
|
|
print(f"\nRMSE - Mean: {rmse_mean}, Median: {rmse_median}, Std Dev: {rmse_stdev}, 95% CI: {rmse_ci}")
|
|
print(f"SSIM - Mean: {ssim_mean}, Median: {ssim_median}, Std Dev: {ssim_stdev}, 95% CI: {ssim_ci}")
|
|
|
|
print(f"RMSE: {rmse_mean} ± {rmse_ci[1] - rmse_mean}")
|
|
print(f"SSIM: {ssim_mean} ± {ssim_ci[1] - ssim_mean}")
|
|
|
|
def save_average_diff_map(results, save_path='average_diff_map.png'):
|
|
if not results:
|
|
print("No results available to create an average diff map.")
|
|
return
|
|
|
|
avg_diff_map = None
|
|
|
|
for res in results:
|
|
if avg_diff_map is None:
|
|
avg_diff_map = np.zeros_like(res['diff_mask'])
|
|
|
|
avg_diff_map += res['diff_mask']
|
|
|
|
avg_diff_map /= len(results)
|
|
|
|
avg_diff_map = (avg_diff_map * 255).astype(np.uint8)
|
|
|
|
cv2.imwrite(save_path, avg_diff_map)
|
|
|
|
# Usage
|
|
save_average_diff_map(results)
|