[CT肺结节]基于KMean肺实质的分割python实现算法

目录

1.序言

2.python实现

3.分割算法的流程及结果如下

4.这是一个人的一次CT检查的序列,挑选部分作为展示


1.序言

针对医疗领域中的病灶检测中,采用分割算法最为常见。但是,针对特定脏器内的病灶检测,一直存在一个特别易出现假阳性的地方,就是脏器外的误检测。

本文就主要针对CT肺部,对肺实质部分就行切割,去除掉除肺部之外的组织干扰,内容如下:PS,针对肺结节类型的分割前处理中,一般会引入肺实质分割,但是,该方法不能适用于所有的肺部分割中的前处理。因为针对较大的病灶范围,会使得病灶部分一同被切除掉,这是我们所不想看到的。

分割步骤见后面的分割结果图,相信你能看懂。

  1. 输入是dicom转过后的png图像
  2. 输出就是只留下肺实质的图像

2.python实现

import pydicom
import numpy as np
import os
import matplotlib.pyplot as plt
from glob import glob
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import scipy.ndimage
from skimage import morphology
from skimage import measure
from skimage.transform import resize
from sklearn.cluster import KMeans

import cv2

# Standardize the pixel values
def make_lungmask(img, display=False):
    row_size = img.shape[0]
    col_size = img.shape[1]

    mean = np.mean(img)
    std = np.std(img)
    img = img - mean
    img = img / std
    # Find the average pixel value near the lungs
    # to renormalize washed out images
    middle = img[int(col_size / 5):int(col_size / 5 * 4), int(row_size / 5):int(row_size / 5 * 4)]
    mean = np.mean(middle)
    max = np.max(img)
    min = np.min(img)
    # To improve threshold finding, I'm moving the
    # underflow and overflow on the pixel spectrum
    img[img == max] = mean
    img[img == min] = mean
    #
    # Using Kmeans to separate foreground (soft tissue / bone) and background (lung/air)
    #
    kmeans = KMeans(n_clusters=2).fit(np.reshape(middle, [np.prod(middle.shape), 1]))
    centers = sorted(kmeans.cluster_centers_.flatten())
    threshold = np.mean(centers)
    thresh_img = np.where(img < threshold, 1.0, 0.0)  # threshold the image

    # First erode away the finer elements, then dilate to include some of the pixels surrounding the lung.
    # We don't want to accidentally clip the lung.

    eroded = morphology.erosion(thresh_img, np.ones([3, 3]))
    dilation = morphology.dilation(eroded, np.ones([8, 8]))

    labels = measure.label(dilation)  # Different labels are displayed in different colors
    label_vals = np.unique(labels)
    regions = measure.regionprops(labels)
    good_labels = []
    for prop in regions:
        B = prop.bbox
        if B[2] - B[0] < row_size / 10 * 9 and B[3] - B[1] < col_size / 10 * 9 and B[0] > row_size / 5 and B[
            2] < col_size / 5 * 4:
            good_labels.append(prop.label)
    mask = np.ndarray([row_size, col_size], dtype=np.int8)
    mask[:] = 0

    #
    #  After just the lungs are left, we do another large dilation
    #  in order to fill in and out the lung mask
    #
    for N in good_labels:
        mask = mask + np.where(labels == N, 1, 0)
    mask = morphology.dilation(mask, np.ones([10, 10]))  # one last dilation

    if (display):
        fig, ax = plt.subplots(3, 2, figsize=[12, 12])
        ax[0, 0].set_title("Original")
        ax[0, 0].imshow(img, cmap='gray')
        ax[0, 0].axis('off')
        ax[0, 1].set_title("Threshold")
        ax[0, 1].imshow(thresh_img, cmap='gray')
        ax[0, 1].axis('off')
        ax[1, 0].set_title("After Erosion and Dilation")
        ax[1, 0].imshow(dilation, cmap='gray')
        ax[1, 0].axis('off')
        ax[1, 1].set_title("Color Labels")
        ax[1, 1].imshow(labels)
        ax[1, 1].axis('off')
        ax[2, 0].set_title("Final Mask")
        ax[2, 0].imshow(mask, cmap='gray')
        ax[2, 0].axis('off')
        ax[2, 1].set_title("Apply Mask on Original")
        ax[2, 1].imshow(mask * img, cmap='gray')
        ax[2, 1].axis('off')

        plt.show()
    return mask

def raw2mask():
    int_path = r"E:\image_gen\image"
    i=0
    for root, dirs, files in os.walk(int_path):
        for filename in files:  # 遍历所有文件
            i+=1
            print(filename)
            path = os.path.join(root,filename)
            img = cv2.imread(path)
            gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            #cv2.imshow("32",img)
            mask = make_lungmask(gray, display=False)
            Img = np.hstack((gray, mask*gray))
            cv2.imwrite(r"./results/" + filename, Img)


if __name__ == '__main__':

    raw2mask()

3.分割算法的流程及结果如下

注意:display=True

[CT肺结节]基于KMean肺实质的分割python实现算法_第1张图片

4.这是一个人的一次CT检查的序列,挑选部分作为展示

[CT肺结节]基于KMean肺实质的分割python实现算法_第2张图片

本人才疏学浅,本博客留作笔记之用。若恰巧也对你有所帮助,欢迎左侧关注微信公众号支付宝赞赏。有一位专业知识传播者,等待你的喂养。谢谢

更多科技、数码、理财、生活交流,我们移步今日头条,欢迎关注“钱多多先森”。再见

你可能感兴趣的:(CT肺结节)