在医学图像的预处理中,CT图像中总是包含机床,对于后续的操作总会有影响,所以一般都要将相应的机床进行去除。我们可以通过相应的腐蚀膨胀等算法进行去除,但是本篇博客不是利用这种方式进行去除的。是在python代码中手动描绘所取去除的区域,将床位进行去除的。因为CT扫描时,床位的位置几乎是固定不变的,通过描绘一个mask,将这个mask应用到该序列下所有的文件中,就可以进行去除床位。
一、代码解释
代码实现如下。
import pydicom
import numpy as np
import matplotlib.pyplot as plt
import cv2
import os
# 读取 DICOM 文件
def read_dicom(dicom_path):
dicom = pydicom.dcmread(dicom_path)
return dicom.pixel_array
# 显示 DICOM 图像并获取用户选择的区域
def get_polygon_from_user(image):
fig, ax = plt.subplots()
ax.imshow(image, cmap='gray')
print("Please select vertices of the region and press Enter when done.")
# 用户选择区域的顶点
points = plt.ginput(n=-1, timeout=0) # 无限次点击,直到按 Enter 结束选择
plt.close(fig)
return np.array(points, dtype=np.int32)
# 使用选择的多边形区域处理图像
def apply_polygon_mask(image, polygon_points):
mask = np.zeros(image.shape, dtype=np.uint8)
cv2.fillPoly(mask, [polygon_points], 1) # 使用选择的区域创建掩码
# 将选择的区域填充为黑色
processed_image = np.where(mask == 1, 0, image)
return processed_image
# 保存处理后的图像到 DICOM 文件
def save_dicom(image, dicom_path, output_path):
dicom = pydicom.dcmread(dicom_path)
dicom.PixelData = image.tobytes()
dicom.save_as(output_path)
# 处理单张切片,格式是dicom格式的数据
def process_slicer(dicom_path, output_path):
# 读取 DICOM 图像数据
image = read_dicom(dicom_path)
# 获取用户选择的区域
polygon_points = get_polygon_from_user(image)
# 应用掩码,将选择的区域填充为黑色
processed_image = apply_polygon_mask(image, polygon_points)
# 保存处理后的图像到 DICOM 文件
save_dicom(processed_image, dicom_path, output_path)
# 将文件夹中的多个dicom数据去除床位
def process_batch(dicom_files_path, output_files_path):
original_slicers = os.listdir(dicom_files_path)
img = read_dicom(os.path.join(dicom_files_path, original_slicers[1]))
polygon_points = get_polygon_from_user(img)
for original_slicer in original_slicers:
dicom_path = os.path.join(dicom_files_path, original_slicer)
img = read_dicom(dicom_path)
process_image = apply_polygon_mask(img, polygon_points)
output_path = os.path.join(output_files_path, original_slicer) # 存储的文件名
save_dicom(process_image, dicom_path, output_path)
#这是处理单个dicom文件
if __name__ == "__main__":
dicom_path = r'C:\Users\123\Desktop\1\AAA\CT.1.2.840.113619.2.437.3.17433297.595.1697523548.104.1'
#保存的文件名称
output_path = r'C:\Users\123\Desktop\1\BBB\CT.1.2.840.113619.2.437.3.17433297.595.1697523548.104.1'
process_slicer(dicom_path, output_path)
#这是处理多个dicom文件
if __name__ == "__main__":
dicom_path = r'C:\Users\123\Desktop\1\AAA' # 读取 DICOM 文件路径
output_path = r'C:\Users\123\Desktop\1\BBB' # 处理后的 DICOM 文件保存路径
process_batch(dicom_path, output_path)
AAA文件夹内容如图所示,这里面的文件都是dicom格式,BBB也是一个文件夹。
二、操作演示(以多个dicom文件为例)
1、直接在pycharm中运行代码。如图所示
2、后左击鼠标,画出需要去除的区域,之后点击键盘中的Enter键。
3、再打开输出的文件夹查看相应的效果。
原始图像:
去除床位的图像:
三、可能出现的问题:
在pycharm中运行代码,有些同学可能没有出现这样的界面。
解决办法:设置->工具->python图,将在工具窗口中显示绘图前面的勾去掉。