医学图像CT预处理,分割肺部(不只是肺实质,整个肺)

肺部多病种研究需要同时检测肺实质中的结节、索条和心脏、血管中的动脉硬化,而网上只存在肺实质的提取,索性自己写一个,先阈值化,后对背景进行flood_fill算法再取反,同时用到了一些腐蚀膨胀操作。不得不说,skimage真好用,其实skimage也有floodfill,但是不知道为什么出了bug,所以用了cv2的floodfill

import numpy as np
import skimage
from skimage.morphology import disk, rectangle, binary_dilation, binary_erosion, binary_closing, binary_opening, rectangle, remove_small_objects

import SimpleITK as sitk
import matplotlib.pyplot as plt

import cv2


#input np_array with shape (h,w)
#output np_array with shape(h,w)
def seg_whole_lungs(im):
    #背景值是-1000
    output = im.copy()
    mid_img = im.copy()
    
    # 二值化
    mid_img = mid_img > -850
    
    #腐蚀去除噪点
    selem = disk(3)
    mid_img = binary_erosion(mid_img, selem)
          
    #闭运算去除边缘孔洞
    selem = disk(4)
    mid_img = binary_closing(mid_img, selem)
      
    #开运算除掉最下面的线
    selem = rectangle(1,8)
    mid_img = binary_opening(mid_img, selem)
    
    #水漫外围,再取反
    mid_img = fill_water(mid_img)   
    h, w = mid_img.shape[:2]
    binary = np.zeros([h,w], np.uint8)    
    binary[mid_img == 0] = 1
    
    #去除小目标,主要用于去除最下面的奇怪异物
    label_image = remove_small_objects(label(binary), 15000)
    binary = label_image > 0

    output[binary==0] = -1000
        
    return output

def fill_water(image):
    copyImg = image.copy()
    copyImg.astype(np.float32)#cv2要求type必须是float32
    
    #mask必须行和列都加2,且必须为uint8单通道阵列
    h, w = image.shape[:2]
    mask1 = np.zeros([h+2, w+2],np.uint8)   
    mask2 = mask1.copy()
    
    #由于下方出现的弧线可能把图片分割成上下部分,故同时从上下两个方向进行水漫
    cv2.floodFill(np.float32(copyImg), mask1, (1, 1), 1)
    cv2.floodFill(np.float32(copyImg), mask2, (h-1, w-1), 1)
    mask = mask1 | mask2 
    
    #还原为原来的尺寸
    output = mask[1:-1, 1:-1]
    
    return output


以下是效果图
医学图像CT预处理,分割肺部(不只是肺实质,整个肺)_第1张图片
医学图像CT预处理,分割肺部(不只是肺实质,整个肺)_第2张图片

你可能感兴趣的:(实用代码,医学图像处理,ct,分割)