只获得肺部的二值图像
Posted
技术标签:
【中文标题】只获得肺部的二值图像【英文标题】:Getting just a binary image of the lungs 【发布时间】:2021-05-28 12:17:24 【问题描述】:我有一个问题,我正在努力制作肺部的纯二进制蒙版,其中像素值是肺部内部的 1 和肺部外部的 1。我使用了 kmeans 和 otsu 以及其他一些方法来分割肺部。我将附上一些示例图片。
First Example
Second example, same patient/CT. I have no idea why this one has a circle around it
这是一个 3d numpy 数组的链接。它包含所有切片,因此您可能只想尝试一个切片。
https://drive.google.com/file/d/1nktGBYZGz1iJDR_-yarzlRs-c4xOp__9/view?usp=sharing
如您所见,肺被很好地分割。 (图片中间是白色的)。有什么方法可以让我识别出中间的白色斑点(肺)并将其外部的每个像素都变成黑色(0?)如果有人可以指导我,我将非常感谢您的帮助。
这是我用来分割肺的代码(制作二进制掩码):
def HUValueSegmentation(image, fill_lung_structures=True):
# not actually binary, but 1 and 2.
# 0 is treated as background, which we do not want
binary_image = np.array(image > -320, dtype=np.int8)+1
labels = measure.label(binary_image)
# Pick the pixel in the very corner to determine which label is air.
# Improvement: Pick multiple background labels from around the patient
# More resistant to "trays" on which the patient lays cutting the air
# around the person in half
background_label = labels[0,0,0]
#Fill the air around the person
binary_image[background_label == labels] = 2
# Method of filling the lung structures (that is superior to something like
# morphological closing)
if fill_lung_structures:
# For every slice we determine the largest solid structure
for i, axial_slice in enumerate(binary_image):
axial_slice = axial_slice - 1
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
binary_image -= 1 #Make the image actual binary
binary_image = 1-binary_image # Invert it, lungs are now 1
# Remove other air pockets insided body
labels = measure.label(binary_image, background=0)
l_max = largest_label_volume(labels, bg=0)
if l_max is not None: # There are air pockets
binary_image[labels != l_max] = 0
return binary_image
【问题讨论】:
【参考方案1】:由于肺部位于遮罩上一个大的负区域的中间,我通过对图像中最大负区域内的区域进行 bitwise_and 过滤掉了遮罩的其余部分。
编辑:我根本没有更改代码的主体,但我将其修改为将 numpy 数组作为一系列图像。
import cv2
import numpy as np
# load numpy array
images = np.load("array.npy");
# do the lung thing
counter = 0;
for img in images:
# convert to uint8
img *= 255;
inty = img.astype(np.uint8);
# dilate
kernel = np.ones((3,3), np.uint8);
mask = cv2.dilate(inty, kernel, iterations = 1);
# invert
mask = cv2.bitwise_not(mask);
# contours # OpenCV 3.4, this returns (contours, _) on OpenCV 2 and 4
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);
# find biggest
biggest = None;
big_size = -1;
for con in contours:
area = cv2.contourArea(con);
if area > big_size:
big_size = area;
biggest = con;
# draw fill mask
mask2 = np.zeros_like(mask);
cv2.drawContours(mask2, [biggest], -1, (255), -1);
# combine
lungs_mask = cv2.bitwise_and(inty, mask2);
# show
cv2.imshow("Lungs", inty);
cv2.imshow("Mask", lungs_mask);
cv2.waitKey(30);
【讨论】:
非常感谢。这是一个 3d 卷,所以我知道我需要逐个切片。我有一个 numpy 3d 数组,我将逐个切片迭代并尝试使用您的方法。但是,您只是根据我发布的照片(作为您的输入数据)执行了此方法。我遇到了很多错误,就像您从彩色 png 照片中执行的方法一样。你明白我的问题吗?我认为我的 numpy 数组就像变量“灰色”(代码的顶部)但是当我尝试了很多事情时似乎没有任何结果。 你能把 numpy 数组贴出来让我试试看吗? 您希望我实际发布单个切片的所有 512x512 值吗?或者有没有更简单的方法来上传一个 numpy 数组? 您可以使用 numpy.save(array) 将数组保存为文件。 嗯,我不确定将保存的 npy 文件上传到 *** 的位置。我只能看到图片选项。我可以通过电子邮件发送给您吗?以上是关于只获得肺部的二值图像的主要内容,如果未能解决你的问题,请参考以下文章