0.需要使用的软件及版本

3D Slicer 5.4.0,mimics20.0,Photoshop,Python。

1.RT格式的文件通过3D Slicer转换成vtm格式

  软件版本:3D Slicer 5.4.0。
  安装完3D Slicer之后需要安装一个SlicerRT的扩展程序插件。
  具体步骤
  ①View -> Extensions Manager。

1-1

  ②install Extensions -> 搜索”SlicerRT",点击"install"。

1-2

  安装完之后,在Manage Extersions中,就可以看到已经安装好的插件。

安装

PS:还有一个插件的包,直接本地安装,装完之后也可以查看RT文件。不知道有没有用,都装着吧。

查看文档

  数据处理:
  打开 3D Slicer,打开RT文件(File->Add Data->Choose File to Add),Description选择”DICOM import“。

文件导入

  选择RT格式的文件载入。

选择格式

  左侧面板的Loaded data就会显示已经加载进来的标签。

加载数据

  上面的modules选择”Segmentation“模式,点击"show 3D",右侧就会出现标签的3D效果图。

展示3D效果图

  导出标签的vtm文件:File->Save Data,只选择segmentation进行保存,文件格式选择.vtm,可以修改存放vtm文件的路径,点击save。

导出文件

  可以得到一个.vtm文件,和一个包含所有标签的.vtp文件的文件夹。

查看导出文件

2.vtm通过3D Slicer转换成stl格式

  打开3D Slicer,File->Add Data-Choose File to Add,选择要导入的.vtm文件,Description选择"Segmentation"模式,点击OK。

导入数据

  此时的场景就创建好了。

场景创建

  将需要的标签的可视化打开(就是边上有个小眼睛),右击鼠标,选择"Export visible segments to models"。

标签可视化

  生成了刚刚所选标签导出的模型。

模型生成

  保存文件:File->Save Data(或者 Ctrl+S),可以直接进行文件的命名,文件格式(File Format)选择.stl格式,也可以修改文件的保存路径,点击Save。

文件保存

  生成了导出的stl文件。

查看文件

3.stl通过mimics转换成bmp图片

  软件版本:mimics20.0。
  打开mimics,File->New Project,打开需要进行标签配对的的CT图像文件夹,点击next,在弹出的窗口点击convert,接着点击OK。

打开文件

  导入STL文件:File->Import->STL。鼠标右击导入的STL,点击“Calculate Mask from Object”。

文件导入

  点击"Apply"。

应用

  此时标签跟CT图像对应上了,我们只保留标签信息。
  View -> 2D Viewports -> Mask Shade -> Binary。

保留标签

  将mask的颜色改成白色,方便后面的格式转化。

改变mask颜色1
改变mask颜色2

  导出BMP文件:File->Export->BMP/JPEG,选择Axial视角的图像,范围"all",文件类型"bmp",自定义bmp文件保存路径,点击"Apply"。

导出文件

4.通过PS将bmp文件二值化

  ①打开”动作“面板:视图-动作。
  ②添加已经创建好的动作:在“动作”面板中,点击右上角的菜单栏(三条横线的图标),然后选择“载入动作”,选择已经创建好的动作载入。

动作
保存动作

  ③批处理:文件->自动->批处理,选择载入的动作,选择要处理的.bmp图片所在的文件夹,选择导出的文件夹位置,随后一直按Enter键就可以输出处理好的bmp图片了。

批处理

5.BMP2NII:交给代码处理

附上代码。
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
from PIL import Image
import numpy as np
import SimpleITK as sitk
import os

# 定义基础文件夹路径
base_folder = r"D:\Data\data processing"
bmp_folser = os.path.join(base_folder, "3.bmp_new")

# 获取基础文件夹下的所有文件夹
subfolders = [f for f in os.listdir(bmp_folser) if os.path.isdir(os.path.join(bmp_folser, f))]

for subfolder in subfolders:
print(f"Processing folder: {subfolder}")

# 定义输入和输出文件夹路径
input_folder_bmp = os.path.join(base_folder, f"3.bmp_new\{subfolder}")
output_folder_bmp = os.path.join(base_folder, f"3.bmp2\{subfolder}")
output_folder_nii = os.path.join(base_folder, f"4.NII\{subfolder}")
output_file_label = os.path.join(base_folder, f"5.Label_new\{subfolder}_label.nii")

try:
# 创建输出文件夹(如果不存在)
os.makedirs(output_folder_bmp, exist_ok=True)
os.makedirs(output_folder_nii, exist_ok=True)

# 获取输入文件夹中所有bmp文件的路径
bmp_files = [f for f in os.listdir(input_folder_bmp) if f.endswith('.bmp')]

# 循环处理每个bmp文件
for bmp_file in bmp_files:
bmp_path = os.path.join(input_folder_bmp, bmp_file)

try:
# 打开bmp文件
image = Image.open(bmp_path)

# 等比例缩放到512x512
new_size = (512, 512)
image = image.resize(new_size, Image.LANCZOS)

# 将图像转换为1位图像(单色位图)
image = image.convert('1')

# 构造输出文件的路径
output_path_bmp = os.path.join(output_folder_bmp, os.path.splitext(bmp_file)[0] + '_1bit.bmp')

# 保存为1位图像
image.save(output_path_bmp)

# 读取BMP文件
bmp_image = np.array(image)

# 将数据转换为uint8
bmp_image = bmp_image.astype(np.uint8)

# 将numpy数组转换为SimpleITK图像类型
sitk_image = sitk.GetImageFromArray(bmp_image)

# 构造输出文件名
output_file_nii = os.path.join(output_folder_nii, os.path.splitext(bmp_file)[0] + '.nii')

# 保存图像为NII格式
sitk.WriteImage(sitk_image, output_file_nii)
except Exception as e:
print(f"Error processing file {bmp_file}: {e}")

# 处理Label NII文件
# 获取输入文件夹中所有NII文件的路径
nii_files = [os.path.join(output_folder_nii, f) for f in os.listdir(output_folder_nii) if f.endswith('.nii')]

# 创建一个空的SimpleITK图像列表
sitk_images = []

# 循环处理每个NII文件
for nii_file in nii_files:
# 读取NII文件并将其添加到列表中
try:
sitk_image = sitk.ReadImage(nii_file)
sitk_images.append(sitk_image)
except Exception as e:
print(f"Error reading NII file {nii_file}: {e}")

# 使用SimpleITK的JoinSeries函数将图像列表合并为一个4D图像
output_image = sitk.JoinSeries(sitk_images)

# 设置所需的Voxel Spacing和Origin
desired_spacing = [1.03711, 1.03711, 5.0]
desired_origin = [-265.5, -207.5, -833.0]
output_image.SetSpacing(desired_spacing)
output_image.SetOrigin(desired_origin)

# 保存输出图像
output_label_path = os.path.join(base_folder, f"5.Label\{subfolder}_label.nii")
sitk.WriteImage(output_image, output_label_path)

print(f"Processing completed for folder: {subfolder}")
except Exception as ex:
print(f"Error processing folder {subfolder}: {ex}")

print("All folders processed.")