MRI(脑肿瘤)图像处理和分割,去除颅骨

时间:2018-04-14 17:32:51

标签: python image-processing object-detection image-segmentation

我需要图像分割方面的帮助。我有脑肿瘤的MRI图像。我需要从MRI中移除颅骨(头骨)然后仅切除肿瘤对象。我怎么能在python中做到这一点?与图像处理。我试过制作轮廓,但我不知道如何找到并移除最大的轮廓并且只获得没有头骨的大脑。 非常感谢。

def get_brain(img):
  row_size = img.shape[0]
  col_size = img.shape[1]

  mean = np.mean(img)
  std = np.std(img)
  img = img - mean
  img = img / std

 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)


  img[img == max] = mean
  img[img == min] = mean

  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


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

这些图像与我正在看的图像类似:

Skull + Brain

Skull + Brain 2

感谢您的回答。

2 个答案:

答案 0 :(得分:2)

初步

一些初步代码:

%matplotlib inline
import numpy as np
import cv2
from matplotlib import pyplot as plt
from skimage.morphology import extrema
from skimage.morphology import watershed as skwater

def ShowImage(title,img,ctype):
  plt.figure(figsize=(10, 10))
  if ctype=='bgr':
    b,g,r = cv2.split(img)       # get b,g,r
    rgb_img = cv2.merge([r,g,b])     # switch it to rgb
    plt.imshow(rgb_img)
  elif ctype=='hsv':
    rgb = cv2.cvtColor(img,cv2.COLOR_HSV2RGB)
    plt.imshow(rgb)
  elif ctype=='gray':
    plt.imshow(img,cmap='gray')
  elif ctype=='rgb':
    plt.imshow(img)
  else:
    raise Exception("Unknown colour type")
  plt.axis('off')
  plt.title(title)
  plt.show()

作为参考,这是您链接到的大脑+头骨之一:

#Read in image
img           = cv2.imread('brain.png')
gray          = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ShowImage('Brain with Skull',gray,'gray')

Brain with Skull

提取面膜

如果可以将图像中的像素分为两个不同的强度类别,即,如果它们具有双峰直方图,则可以使用Otsu's method将其阈值化为二进制掩码。让我们检查一下这个假设。

#Make a histogram of the intensities in the grayscale image
plt.hist(gray.ravel(),256)
plt.show()

Histogram

好的,数据很好地是双峰的。让我们应用阈值,看看我们如何做。

#Threshold the image to binary using Otsu's method
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU)
ShowImage('Applying Otsu',thresh,'gray')

Tresholded brain+skull

如果将蒙版叠加到原始图像上,事情会更容易看到

colormask = np.zeros(img.shape, dtype=np.uint8)
colormask[thresh!=0] = np.array((0,0,255))
blended = cv2.addWeighted(img,0.7,colormask,0.1,0)
ShowImage('Blended', blended, 'bgr')

Mask overlaid on brain+skull

提取大脑

大脑与面具的重叠部分(以红色显示)非常完美,我们就在这里停止。为此,让我们提取连接的组件并找到最大的组件,即大脑。

ret, markers = cv2.connectedComponents(thresh)

#Get the area taken by each component. Ignore label 0 since this is the background.
marker_area = [np.sum(markers==m) for m in range(np.max(markers)) if m!=0] 
#Get label of largest component by area
largest_component = np.argmax(marker_area)+1 #Add 1 since we dropped zero above                        
#Get pixels which correspond to the brain
brain_mask = markers==largest_component

brain_out = img.copy()
#In a copy of the original image, clear those pixels that don't correspond to the brain
brain_out[brain_mask==False] = (0,0,0)
ShowImage('Connected Components',brain_out,'rgb')

Brain extracted with connected components

考虑第二个大脑

在第二张图像中再次运行此操作会产生带有许多孔的遮罩:

Second Brain

我们可以使用closing transformation来关闭许多这样的漏洞:

brain_mask = np.uint8(brain_mask)
kernel = np.ones((8,8),np.uint8)
closing = cv2.morphologyEx(brain_mask, cv2.MORPH_CLOSE, kernel)
ShowImage('Closing', closing, 'gray')

Brain mask with holes closed

我们现在可以提取大脑:

brain_out = img.copy()
#In a copy of the original image, clear those pixels that don't correspond to the brain
brain_out[closing==False] = (0,0,0)
ShowImage('Connected Components',brain_out,'rgb')

Second brain with better mask

(请注意,如果您出于学术目的使用它,则学术诚信需要适当的归属。有关详细信息,请与我联系。)

答案 1 :(得分:0)

您是否尝试过使用python skull_stripping.py 您可以修改参数,但通常效果很好。

有一些使用深度学习进行头骨剥离的新研究,我发现它很有趣:

https://github.com/mateuszbuda/brain-segmentation/tree/master/skull-stripping