- github官方库
https://github.com/deepmind/surface-distance - 代码示例
import os
import numpy as np
import codecs
import SimpleITK as sitk
import pandas as pd
import torch
import surface_distance as surfdist
def readlines(file):
"""
read lines by removing '\n' in the end of line
:param file: a text file
:return: a list of line strings
"""
fp = codecs.open(file, 'r', encoding='utf-8')
linelist = fp.readlines()
fp.close()
for i in range(len(linelist)):
linelist[i] = linelist[i].rstrip('\n') # cancel '\n' per line
return linelist
def read_test_txt(imlist_file):
'''
:param imlist_file: image list file path
:return: image list path divided into two list
'''
lines = readlines(imlist_file)
num_cases = int(lines[0])
if (len(lines) - 1) < (num_cases * 2):
raise ValueError('too few lines in imlist file')
im_list, seg_list = [], []
for i in range(num_cases):
im_path, seg_path = lines[1 + i * 2].strip(), lines[2 + i * 2].strip()
assert os.path.exists(im_path), 'image not exist: {}'.format(im_path)
assert os.path.exists(seg_path), 'mask not exist: {}'.format(seg_path)
im_list.append(im_path)
seg_list.append(seg_path)
return im_list, seg_list
def hausdorff_95(input_np, target_np, num_class, spacing, epsilon=1e-6):
'''
:params input_tensor: the result of segmentation
:params target: ground true mask
:params num_class: label number
'''
Hausdorff_95_score = []
for i in range(1, num_class):
input_np_copy = input_np.copy()
target_np_copy = target_np.copy()
input_np_copy[input_np_copy != i] = 0
target_np_copy[target_np_copy != i] = 0
input_np_copy = input_np_copy.astype(np.bool)
target_np_copy = target_np_copy.astype(np.bool)
# compute Hausdorff_95 score
surface_distances = surfdist.compute_surface_distances(target_np_copy, input_np_copy, spacing)
hd_dist_95 = surfdist.compute_robust_hausdorff(surface_distances, 95)
Hausdorff_95_score.append(hd_dist_95)
print('class = {}, Hausdorff_95_score = {}'.format(i, hd_dist_95))
return Hausdorff_95_score
def val(input_path, results_csv):
if input_path.endswith('txt'):
gt_list, pre_list = read_test_txt(input_path)
else:
raise ValueError('image test_list must either be a txt file or a csv file')
Hausdorff_95_score_record = pd.DataFrame(columns = ['case_name', 'left', 'right'])
for gt_path, pre_path in zip(gt_list, pre_list):
print('{}: {}'.format(gt_path, pre_path))
gt_mask = sitk.ReadImage(gt_path)
pre_mask = sitk.ReadImage(pre_path)
spacing = gt_mask.GetSpacing()
case_name = gt_path.split('/')[-1].split('.')[0]
gt_mask_np = sitk.GetArrayFromImage(gt_mask).astype(float)
pre_mask_np = sitk.GetArrayFromImage(pre_mask).astype(float)
num_label = np.unique(gt_mask_np)
num_class = len(num_label)
Hausdorff_95_score = hausdorff_95(pre_mask_np, gt_mask_np, num_class, spacing)
if num_class == 3:
df = pd.DataFrame({
'case_name':case_name,
'left': Hausdorff_95_score[0].item(),
'right': Hausdorff_95_score[1].item()
},index=[0])
if num_class == 2:
df = pd.DataFrame({
'case_name': case_name,
'seg_name':Hausdorff_95_score[0].item()
},index=[0])
Hausdorff_95_score_record = Hausdorff_95_score_record.append(df)
Hausdorff_95_score_record.to_csv(results_csv, index=None)
input_path = 'dice_20220509_1.txt'
results_csv = '20220509_1.csv'
val(input_path, results_csv)
- Reference
https://blog.csdn.net/lijiaqi0612/article/details/113925215
https://blog.csdn.net/hajlyx/article/details/105809129