如何解决分割结果与Ground Truth颜色不匹配的图像分割评估问题?
图像分割结果与Ground Truth的评估方案(解决颜色分配差异问题)
你遇到的核心问题是分割结果的标签颜色和Ground Truth(GT)的标注规则不匹配,但区域划分是对的——这种情况下,所有不依赖标签数值/颜色、只关注像素分组一致性的评估指标都适用,以下是具体方案:
核心思路
跳过颜色对比,直接比较「像素被划分到同一区域的逻辑」:先通过算法找到分割结果标签和GT标签的最优对应关系(最大化区域重叠),再计算匹配后的区域重叠度或分组一致性。
推荐的评估指标
1. 调整兰德指数(Adjusted Rand Index, ARI)
- 完全不关心标签的数值/颜色,只统计「两个分割结果中,像素对的分组是否一致」:要么两个像素在分割结果和GT里都属于同一区域,要么都属于不同区域。
- 修正了随机分组带来的偏差,数值范围是[-1,1],越接近1说明分割和GT的一致性越高。
- 直接调用现成库就能计算,不需要额外处理标签映射。
2. 平均交并比(mIoU,带标签映射)
- 先通过匈牙利算法找到分割结果标签和GT标签的最优对应关系,再计算每个对应区域的IoU(交并比),最后取平均值。
- 能直观反映每个区域的分割精度,是分割任务中最常用的指标之一。
3. Dice系数(带标签映射)
- 和IoU类似,计算两个区域的重叠程度,公式为
2*|A∩B|/(|A|+|B|),同样需要先做标签映射,再求平均。 - 对小区域的重叠更敏感,在医学影像分割场景中常用。
代码实现示例
直接用分割得到的标签图(labels1_NCUT)和GT的标签图计算,不需要用彩色的分割结果图:
import numpy as np import cv2 as cv from scipy.optimize import linear_sum_assignment from sklearn.metrics import adjusted_rand_score from skimage.measure import label # 读取并处理GT:把彩色GT转成灰度标签图 gt_img = cv.imread(GT_PATH) gt_img = cv.cvtColor(gt_img, cv.COLOR_BGR2RGB) gt_gray = cv.cvtColor(gt_img, cv.COLOR_RGB2GRAY) gt_labels = label(gt_gray) # 生成GT的标签图,每个区域对应唯一整数 # 你的分割结果标签图(来自代码中的labels1_NCUT) seg_labels = labels1_NCUT # 1. 计算调整兰德指数 ari_score = adjusted_rand_score(gt_labels.flatten(), seg_labels.flatten()) print(f"调整兰德指数(ARI):{ari_score:.4f}") # 2. 计算带标签映射的mIoU def calculate_miou(seg_labels, gt_labels): # 获取分割结果和GT的所有唯一标签 seg_unique = np.unique(seg_labels) gt_unique = np.unique(gt_labels) # 构建混淆矩阵:行是分割标签,列是GT标签 conf_matrix = np.zeros((len(seg_unique), len(gt_unique)), dtype=np.int64) for seg_idx, seg_lab in enumerate(seg_unique): for gt_idx, gt_lab in enumerate(gt_unique): conf_matrix[seg_idx, gt_idx] = np.sum((seg_labels == seg_lab) & (gt_labels == gt_lab)) # 匈牙利算法找最优标签匹配(最大化重叠像素数) row_ind, col_ind = linear_sum_assignment(-conf_matrix) # 计算每个匹配类别的IoU iou_list = [] for seg_idx, gt_idx in zip(row_ind, col_ind): intersection = conf_matrix[seg_idx, gt_idx] union = np.sum(conf_matrix[seg_idx, :]) + np.sum(conf_matrix[:, gt_idx]) - intersection iou = intersection / union if union != 0 else 0.0 iou_list.append(iou) return np.mean(iou_list) miou_score = calculate_miou(seg_labels, gt_labels) print(f"带标签映射的平均交并比(mIoU):{miou_score:.4f}")
注意事项
- 不要用彩色的分割结果图(
out1)来评估,直接用分割生成的标签图(labels1_NCUT)——标签图里的整数只是区域标识,和颜色无关。 - 如果GT是手动标注的彩色图,一定要先转成灰度标签图(每个区域对应唯一灰度值),再和分割标签图对比。
内容的提问来源于stack exchange,提问作者PwNzDust
相关产品推荐
相关产品推荐

