如何修改shap.KernelExplainer的mask_image函数保留图像背景零值
解决方案
你可以根据实际需求选择以下两种修改方案:
方案1:所有被mask的区域默认填充零(最常用)
如果你的需求是所有被隐藏的区域都和原图像背景保持一致填充为零,仅需修改默认背景的生成逻辑即可:
def mask_image(zs, segmentation, image, background=None): if background is None: # 替换原有的均值计算逻辑,生成和图像通道数、数据类型匹配的全零背景 background = np.zeros(image.shape[-1], dtype=image.dtype) out = np.zeros((zs.shape[0], image.shape[0], image.shape[1], image.shape[2]), dtype=image.dtype) for i in range(zs.shape[0]): out[i,:,:,:] = image for j in range(zs.shape[1]): if zs[i,j] == 0: out[i][segmentation == j,:] = background return out
修改说明
- 把默认背景从整张图像的通道均值改为和图像数据类型、通道数匹配的全零数组,所有被mask的区域都会填充为0,和你原始医学图像的背景值完全一致
- 补充了输出数组的
dtype匹配逻辑,避免原图像为uint8类型时出现的数值精度、格式不匹配问题 - 保留了传入自定义
background参数的能力,原有自定义背景的使用逻辑不受影响
方案2:仅保留原图像固有零背景,非背景区域mask时仍用均值填充
如果你的需求是只有原图像本身就是零值的背景区域不被修改,非背景的组织区域被mask时仍然使用图像均值填充,可以用以下版本:
def mask_image(zs, segmentation, image, background=None): if background is None: background = image.mean((0,1)) out = np.zeros((zs.shape[0], image.shape[0], image.shape[1], image.shape[2]), dtype=image.dtype) for i in range(zs.shape[0]): out[i,:,:,:] = image for j in range(zs.shape[1]): if zs[i,j] == 0: # 仅对非零像素的区域替换为背景,零值背景区域保留原值 seg_mask = segmentation == j non_zero_mask = (out[i, seg_mask, :] != 0).any(axis=-1) out[i, seg_mask, :][non_zero_mask] = background return out
修改说明
- 仅对被mask的分割块中,原本像素值非零的区域替换为背景值
- 原图像中已经是零值的背景区域即使被mask也会保留原值
内容的提问来源于stack exchange,提问作者carolina
相关产品推荐
相关产品推荐

