def segment_lung_mask(image, speedup=4):
def largest_label_volume(im, bg=-1):
vals, counts = np.unique(im, return_counts=True)
counts = counts[vals != bg]
vals = vals[vals != bg]
if len(counts) > 0:
return vals[np.argmax(counts)]
else:
return None
if speedup>1:
smallImage = transform.downscale_local_mean(image,(1,speedup,speedup));
else:
smallImage = image;
# not actually binary, but 1 and 2.
# 0 is treated as background, which we do not want
binary_image = np.array((smallImage < -320) & (smallImage>-1400), dtype=np.int8)
#return binary_image;
for i, axial_slice in enumerate(binary_image):
axial_slice = 1-axial_slice
labeling = measure.label(axial_slice)
l_max = largest_label_volume(labeling, bg=0)
if l_max is not None: #This slice contains some lung
binary_image[i][(labeling!=l_max)] = 1
# Remove other air pockets insided body
labels = measure.label(binary_image, background=0)
m = labels.shape[0]//2;
check_layers = labels[m-12:m+20:4,:,:];
l_max = largest_label_volume(check_layers, bg=0)
while l_max is not None: # There are air pockets
idx = np.where(check_layers==l_max);
ii = np.vstack(idx[1:]).flatten();
if np.max(ii)>labels.shape[1]-24/speedup or np.min(ii)<24/speedup:
binary_image[labels==l_max] = 0;
labels = measure.label(binary_image, background=0)
m = labels.shape[0]//2;
check_layers = labels[m-12:m+20:4,:,:];
l_max = largest_label_volume(check_layers, bg=0)
else:
binary_image[labels != l_max] = 0
break
if speedup<=1:
return binary_image
else:
res = np.zeros(image.shape,dtype=np.uint8);
for i,x in enumerate(binary_image):
orig = np.copy(x);
x = binary_dilation(x,disk(5))
x = binary_erosion(x,disk(5))
x = np.logical_or(x,orig)
y = transform.resize(x*1.0,image.shape[1:3]);
res[i][y>0.5]=1
return res;
评论列表
文章目录