深度学习,分割后处理之通过填补孔洞,提高分割准确度

Posted Tina姐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习,分割后处理之通过填补孔洞,提高分割准确度相关的知识,希望对你有一定的参考价值。

当我们查看分割结果时,会发现分割内部偶尔会出现这种分割孔洞(hole)。

常识告诉我们,这个器官内部是没有孔洞的,因此,我们通过后处理的方法把它填上,可以提高分割准确度。

这种三维孔洞,我们希望有一种便捷方法,可以直接填补这种三维孔洞。可以使用 SITK 的二值孔洞填补方法。 sitk.BinaryFillhole

  1. sitk.BinaryFillhole

注意: 该函数只针对二值图像(值为0或1)

import SimpleITK as sitk
import os
import glob

imglist= glob.glob('./*.nii.gz')
save_dir = './fillhole'

for img in imglist:
    img_nii = sitk.ReadImage(img, outputPixelType=sitk.sitkUInt16)
    img_fill = sitk.BinaryFillhole(img_nii)
    img_savedir = os.path.join(save_dir, img.split('/')[-1])

    sitk.WriteImage(img_fill, img_savedir)

该例子显示了如何批量填补孔洞,并且保存下来。

  1. 自写一个。

我是主张能用开源工具就用工具,毕竟这些工具都是大牛写的,值得信赖。

但是,我这里还是提供一个github上写的算法。

大致思路: 这个算法提供了三维填充和二维填充,二维填充是选择一个面(如横断面或者冠状面)进行一层一层的填充。

from scipy.ndimage.morphology import binary_fill_holes
import numpy as np
from scipy import ndimage
import nibabel as nib
from skimage.measure import label
import matplotlib.pyplot as plt


def hole_filling(bw, hole_min, hole_max, fill_2d=True):
    bw = bw > 0
    if len(bw.shape) == 2:
        background_lab = label(~bw, connectivity=1)
        fill_out = np.copy(background_lab)
        component_sizes = np.bincount(background_lab.ravel())
        too_big = component_sizes > hole_max
        too_big_mask = too_big[background_lab]
        fill_out[too_big_mask] = 0
        too_small = component_sizes < hole_min
        too_small_mask = too_small[background_lab]
        fill_out[too_small_mask] = 0
    elif len(bw.shape) == 3:
        if fill_2d:
            fill_out = np.zeros_like(bw)
            for zz in range(bw.shape[1]):
                background_lab = label(~bw[:, zz, :], connectivity=1)   # 1表示4连通, ~bw[zz, :, :]1变为0, 0变为1
                # 标记背景和孔洞, target区域标记为0
                out = np.copy(background_lab)
                # plt.imshow(bw[:, :, 87])
                # plt.show()
                component_sizes = np.bincount(background_lab.ravel())
                # 求各个类别的个数
                too_big = component_sizes > hole_max
                too_big_mask = too_big[background_lab]

                out[too_big_mask] = 0
                too_small = component_sizes < hole_min
                too_small_mask = too_small[background_lab]
                out[too_small_mask] = 0
                # 大于最大孔洞和小于最小孔洞的都标记为0, 所以背景部分被标记为0了。只剩下符合规则的孔洞
                fill_out[:, zz, :] = out
                # 只有符合规则的孔洞区域是1, 背景及target都是0
        else:
            background_lab = label(~bw, connectivity=1)
            fill_out = np.copy(background_lab)
            component_sizes = np.bincount(background_lab.ravel())
            too_big = component_sizes > hole_max
            too_big_mask = too_big[background_lab]
            fill_out[too_big_mask] = 0
            too_small = component_sizes < hole_min
            too_small_mask = too_small[background_lab]
            fill_out[too_small_mask] = 0
    else:
        print('error')
        return

    return np.logical_or(bw, fill_out)  # 或运算,孔洞的地方是1,原来target的地方也是1

参数简介

  • bw: array, 待填补的数组
  • hole_min: 孔洞像素的个数最小值,一般为0
  • hole_max: 孔洞像素的个数最大值。
  • fill_2d: True:二维填充。False:三维填充
    只有当孔洞像素值个数在 [hole_min, hole_max] 才会被填补。

算法里面涉及了大量的与或非运算。

调用

filled = hole_filling(arr, 0, 100, fill_2d=True)  # 通过改变bw[zz, :, :],选择轴

你可以对比一下,这三种算法(第二个里面是2种算法)哪个更适合你。

深度学习,分割后处理之通过连通成分分析去除假阳性区域,提高分割准确度

常用的分割后处理方法就是 连通成分分析和填补孔洞,你学会了吗。

文章持续更新,可以关注微信公众号【医学图像人工智能实战营】获取最新动态,一个关注于医学图像处理领域前沿科技的公众号。坚持已实践为主,手把手带你做项目,打比赛,写论文。凡原创文章皆提供理论讲解,实验代码,实验数据。只有实践才能成长的更快,关注我们,一起学习进步~

我是Tina, 我们下篇博客见~

白天工作晚上写文,呕心沥血

觉得写的不错的话最后,求点赞,评论,收藏。或者一键三连

以上是关于深度学习,分割后处理之通过填补孔洞,提高分割准确度的主要内容,如果未能解决你的问题,请参考以下文章

深度学习从入门到精通——图像分割技术原理解析

基于深度学习的图像语义分割技术概述之背景与深度网络架构

基于深度学习的图像分割在高德的实践

(新)基于深度学习的图像语义分割技术概述之5.1度量标准

基于深度学习的图像语义分割技术概述之5.1度量标准

GIS地理处理脚本案例教程——批量栅格分割-批量栅格裁剪-批量栅格掩膜-深度学习样本批量提取