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

用深度学习方法得到的分割结果,会有一些假阳性区域。通过去除这些假阳性区域,可以提高分割结果。

比如说做肾分割,大家都知道,肾只有左右两边有,如果分割结果出现了三个区域,则可以根据常识,去除那个假阳性区域。


image

用到的方法就是 连通成分分析Connected-Components

这里提供两种方法:

1. opencv-python 提供的方法

安装: pip install opencv-python
cv2.connectedComponents & cv2.connectedComponentsWithStats

1.1 cv2.connectedComponents

实例:

import cv2
import numpy as np
img = np.array([[0, 255, 0, 0],
                [0, 0, 255, 255],
                [0, 0, 0, 255],
                [255, 0, 0, 0]], np.uint8)
res, labels = cv2.connectedComponents(img, connectivity=4)
res
Out[5]: 4
labels
Out[6]: 
array([[0, 1, 0, 0],
       [0, 0, 2, 2],
       [0, 0, 0, 2],
       [3, 0, 0, 0]], dtype=int32)

假设 img 是分割结果,值为255的是目标区域,可以发现,目标区域有3块。res代表区域的数量 一共有4块。

labels为经过连通区域分析后的标记,把 4邻域 内相同的值标记为一个类别。这样一共产生了4个区域,分别用【0,1,2,3】表示。

上述例子例子中,参数 connectivity=4 表示在4邻域范围内查找元素,也是可以改成8邻域对比一下

4邻域:A点的上下左右中,假设存在B点和它的值一样,就表示 AB 点属于同一区域。

这样标记后,如果我们觉得3那个区域是假阳性,那我们就可以把3那个区域的值变为0,其余区域的值标记为255,这样就消除掉3这个区域的阳性值了。

label = np.where(labels > 2, 0, labels)
# 把labels中,大于2的值,赋值为0, 其余的就是labels原来的值。这样就剩下了两个区域
print(label)

结果如下: 

[[0 1 0 0]
 [0 0 2 2]
 [0 0 0 2]
 [0 0 0 0]]

1.2 cv2.connectedComponentsWithStats


image

stats 是 bounding box 的信息,N*5的矩阵,行对应每个label,五列分别为 [x0, y0, width, height, area]

参考链接

总结:该方法对二维图像去除假阳性区域很好用,但是无法对三维图像进行操作。

2 cc3d 提供的方法

cc3d 提供了二维和三维的方法实现连通成分分析

  • 3D 方法: 提供 26、18 或 6 个连通邻域划分区域
  • 2D 方法: 提供 4 和 8 个连通域分析。

cc3d github 地址

如何安装

pip install connected-components-3d

测试

测试代码及地址

比如二维图像:


image

原始图像有 [0, 31, 199] 3个值 背景是0,绿色是31, 199是紫色。

img = np.array(Image.open('./testing_img/test2d.png'))[:,:,0]
print(np.unique(img))
image
labels = cc3d.connected_components(labels, connectivity=4)

使用4邻域后,图片多了很多种颜色,每种颜色都代表一个区域,一共有78个区域。

划分成不同区域了,自然能提取出想要的区域。比如把 区域像素<阈值的置为0,从而去除假阳性。或者只保留前两个最大的区域,其余置为0.

最后,附上我真实处理三维数据的代码

import cc3d
import nibabel as nib
from pathlib2 import Path
from tqdm import tqdm
import numpy as np
import os


def main(data, output):
    data = Path(data).resolve()
    output = Path(output).resolve()

    assert data != output, f'postprocess data will replace original data, use another output path'

    if not output.exists():
        output.mkdir(parents=True)

    predictions = sorted(data.glob('*_seg.nii.gz'))
    for pred in tqdm(predictions):
        if not pred.name.startswith('.'):
            vol_nii = nib.load(str(pred))
            affine = vol_nii.affine
            vol = vol_nii.get_fdata()
            vol = post_processing(vol)
            vol_nii = nib.Nifti1Image(vol, affine)

            vol_nii_filename = output / pred.name
            vol_nii.to_filename(str(vol_nii_filename))


def post_processing(vol):
    vol_ = vol.copy()
    vol_[vol_ > 0] = 1
    vol_ = vol_.astype(np.int64)
    vol_cc = cc3d.connected_components(vol_)
    cc_sum = [(i, vol_cc[vol_cc == i].shape[0]) for i in range(vol_cc.max() + 1)]
    cc_sum.sort(key=lambda x: x[1], reverse=True)
    cc_sum.pop(0)  # remove background
    reduce_cc = [cc_sum[i][0] for i in range(1, len(cc_sum)) if cc_sum[i][1] < cc_sum[0][1] * 0.1]
    for i in reduce_cc:
        vol[vol_cc == i] = 0

    return vol


if __name__ == '__main__':
    data = 'output/'  # 分割结果地址,图像为nii.gz  
    output = 'output_remove/' # 移除假阳性后保存地址
    if not os.path.exists(output):
        os.makedirs(output)
    main(data, output)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容