[4c12f9]: / vessel_segment.py

Download this file

110 lines (101 with data), 4.1 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
"""
This file is for plumonary vessels enhancement.
"""
import numpy as np
import SimpleITK as sitk
from scipy import ndimage
import cv2
from itertools import izip_longest
class VesselSegment:
"""
This class is desigened for lung vasculature enhancement, including the methods of:
1. downsampling
2. thresholding
3. 3D region growing
4. filtering small struture
"""
def __init__(self, original, closing):
"""
:param original: the orignal image in ITK formate
:param closing: the Closing result image
:param thval: threshold value (default: 130HU)
:param filter_vol: filter value for removing small struture after region growing (default: 2ml)
"""
self.original_img = original
self.closing_img = sitk.GetArrayFromImage(closing)
self.img = None
self.thval = None
self.filter_vol = None
self.temp_img = None
def erosion(self, lunglabel=[201, 202]):
"""
Shrik the region of lung...
"""
temp = np.zeros_like(self.closing_img)
temp[self.closing_img == lunglabel[0]] = 1
temp[self.closing_img == lunglabel[1]] = 1
Erode_filter = sitk.BinaryErodeImageFilter()
Erode_filter.SetKernelRadius ( 2 ).SetForegroundValue ( 1 )
self.closing_img = sitk.GetArrayFromImage( Erode_filter.Execute ( sitk.GetImageFromArray(temp) ) )
def generate_lung_mask(self, offset = 0):
"""
Generate lung mask
:return: None
"""
self.img = sitk.GetArrayFromImage(self.original_img).copy() - offset
self.img[self.closing_img == 0] = 0
def downsampling(self):
"""
Downsample the input image from [-1024, 0] to [0, 255] for reducing memory requirement.
/ max(0, min(254, (Vorig+1024)/4), v belongs to Lung region
Vds =
\ 255, otherwise
:return: None
"""
temp = (self.img + 1024) / 4
temp[temp > 254] = 254
temp[temp < 0] = 0
self.temp_img = temp
def thresholding(self, thval=130):
"""
Threshold the image with given thresholding value.
:return: None
"""
self.thval = thval
self.temp_img[self.temp_img < thval] = thval
def max_filter(self, filter_size=5):
"""
Implement maximum filter.
:param filter_size: filter size
:return: None
"""
temp = self.temp_img.copy()
temp[temp >= 254] = 0
temp[temp <= self.thval] = 0
self.temp_img = ndimage.filters.maximum_filter(temp, size=filter_size)
def filtering(self, min_size=10, max_size=5000):
"""
Remove the small structure which volumn is less than given value (2ml)
:param min_size:
:return: None
"""
self.filter_vol = min_size
z, y, x = self.temp_img.shape
count_labels = []
for i in range(z):
dist_transform = cv2.distanceTransform(np.uint8(self.temp_img[i, :, :]), cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)
sure_fg = np.uint8(sure_fg)
# Marker labelling
ret, markers = cv2.connectedComponents(sure_fg)
# Add one to all labels so that sure background is not 0, but 1
markers += 1
count_labels = np.asarray([x + y for x, y in izip_longest(count_labels,
np.bincount(markers.flatten()),
fillvalue=0)])
labels = np.arange(0, len(count_labels))
labels[count_labels < min_size] = 0
labels[count_labels > max_size] = 0
labels = np.asarray(list(set(labels)))
for label in labels:
self.temp_img[self.temp_img == label] = 0