Python库使用介绍 LivermorE AI Projector for Computed Tomography LEAP
- 前言
- Projector 用于设定投影参数的类
- 参数解释:
- 其它功能
- load_param(str filepath)
- forward(ipt, project_mode="forward")
- 样例代码
- 后记
前言
github开源代码
python API文档
作为一个纯计算机背景的小白,关于CT的相关工具,专业课是一点没有呀,好不容易找到一个库,网上居然一个教程都没有。所以自己写一个简易的快速上手的教程,希望能帮到同样使用这个库的人。
LEAP这个库的好处在于,它利用pytorch.autograd进行实现,也就是他的输入和输出都是tensor,这实际上十分便于神经网络过程中添加一些这样的投影计算,也可以用来计算loss,真的非常棒。
库的安装大家可以查看开源代码,或许过几天我会写一个安装教程也说不定。
Projector 用于设定投影参数的类
from LEAP_torch import Projector
proj = Projector(forward_project=True,
use_static=False,
use_gpu=False,
gpu_device=None,
batch_size=1)
proj.load_param('...')
参数解释:
- forward_project=None
用于设定该投影类的forward函数是执行前向还是逆向过程。
def forward(self, input, project_mode="forward"):
if self.forward_project is not None:
if self.forward_project:
if self.use_gpu:
return ProjectorFunctionGPU.apply(input, self.proj_data, self.vol_data, self.param_id_t)
else:
return ProjectorFunctionCPU.apply(input, self.proj_data, self.vol_data, self.param_id_t)
else:
if self.use_gpu:
return BackProjectorFunctionGPU.apply(input, self.proj_data, self.vol_data, self.param_id_t)
else:
return BackProjectorFunctionCPU.apply(input, self.proj_data, self.vol_data, self.param_id_t)
else:
if project_mode=="forward":
if self.use_gpu:
return ProjectorFunctionGPU.apply(input, self.proj_data, self.vol_data, self.param_id_t)
else:
return ProjectorFunctionCPU.apply(input, self.proj_data, self.vol_data, self.param_id_t)
elif project_mode=="backward":
if self.use_gpu:
return BackProjectorFunctionGPU.apply(input, self.proj_data, self.vol_data, self.param_id_t)
else:
return BackProjectorFunctionCPU.apply(input, self.proj_data, self.vol_data, self.param_id_t)
如果填写默认的None,并且在forward中不修改project_mode,即如果你什么都不做,那么默认为前向。
-
use_static=False
官网并没有查到相关的说明,但是通过查其c++源码,可以发现,应该是用于确定XYZ顺序的,因为在C++源码里发现了设定volumeDimensionOrder变量。 -
use_gpu=False
-
gpu_device=None
字面意思,后面的gpu_device设置为数字即可,因为在实现过程中,是采用的将volume.to(deivce)这样的pytorch的实现方式。
- batch_size=1
其它功能
load_param(str filepath)
这实际上是一个非常有用的函数,可以一次性解决很多问题,而不需要专门的调用设置不同光的函数这里我们以DOLCE这篇论文中的cfg设置为例,解析每个参数的含义这篇论文好是好,居然没有训练的脚本 。
img_dimx = 512
img_dimy = 512
img_dimz = 1
img_pwidth = 0.8
img_pheight = 0.8
img_offsetx = 0
img_offsety = 0
img_offsetz = 0
proj_geometry = parallel
proj_arange = 60
proj_nangles =240
proj_nrows = 1
proj_ncols = 512
proj_pheight = 0.8
proj_pwidth = 0.8
proj_crow = 0
proj_ccol = 255.5
proj_phis =
proj_sod = 0
proj_sdd = 0
下面我们进行参数解释:
- img_dimx 图像长度
- img_dimy 图像宽度
- img_dimz 图像channel
- img_pwidth volume的x,y轴体素间距
- img_pheight volume的z轴体素间距
- img_offsetx volume的x轴体素偏移,单位为毫米(mm)
- img_offsety volume的y轴体素偏移,单位为毫米(mm)
- img_offsetz volume的z轴体素偏移,单位为毫米(mm)
- proj_geometry 决定投影射线类型,是锥束光线(cone)还是平行光线(parallel)
- proj_arange 设定角度的取值范围,如图为[0,60]度
- proj_nrows 设定投影角度的数目
- proj_nrows x射线探测器的行数
- proj_ncols x射线探测器的列数
- proj_pheight 探测器柱行之间的探测器像素间距(即像素大小),单位为mm
- proj_pwidth 探测器柱列之间的探测器像素间距(即像素大小),单位为mm
- proj_crow 探测器像素行索引,用于从光源经过原点到达探测器的光线(没看懂)
- proj_ccol 探测器的像素列索引为从光源经过原点到达探测器的光线(没看懂)
- proj_phis 如果有设定,则按照设定的角度直接作为角度的取值,类型为str,例如"10,20,30",用逗号隔开
- proj_sod 放射源到物体距离,单位:mm;这也可以看作是放射源到物体的旋转中心的距离
- proj_sdd 放射源到探测器的距离,单位为mm
forward(ipt, project_mode=“forward”)
用于进行投影的函数,可以直接对Projector调用,用法可以将Projector当作一个神经网络的感觉。
# 这是一个样例
pObj = Projector(...)
ct= torch.tensor(size=(1,1,512,512)) # 一般一个CT的Slice切片尺寸是这个样子
sino = pObj(ct, project_mode="forward") # 根据前文的cfg,尺寸为(1,240,1,512)
# 分别为(BatchSize,nAngels,channel,ImgSize)
backsino = pObj(sino, project_mode="backward") # (1,1,512,512)
下面给出几个样例图片,其中图一是sino(由Projector产生),图二是backsino,图三是FBP产生的图像,图四为原图ct。
其中需要说明,sino的这个图是调整nangle=512=img_size,并且交换维度产生的。
样例代码
import matplotlib.pyplot as plt
from guided_diffusion.image_datasets import dataset2run
from dataFidelities.CTClass import set_CTClass
from guided_diffusion import logger
data = dataset2run(
data_dir="./dataset/CKC/",
batch_size=1,
image_size=512,
angle_range=90,
deterministic=True
)
dObj = set_CTClass('cpu', 'cuda:1', use_cuda=False,
batch_size=1, use_static=False,
param_fn="./config/param_parallel512_la90.cfg", rank=1, logger=logger)
for i, j in data.load_data():
plt.imsave('ts.png',i.squeeze(0).squeeze(0),cmap='gray')
plt.imsave('fbp.png',j['condition_fbp'].squeeze(0).squeeze(0),cmap='gray')
tt = dObj.fmult(i)
img = dObj.projector(tt, project_mode='backward')
tt = tt.permute(0, 2, 1, 3)
print(tt.shape)
print(img.shape)
plt.imsave('sino.png',tt.squeeze(0).squeeze(0),cmap='gray')
plt.imsave('rec.png',img.squeeze(0).squeeze(0),cmap='gray')
break
后记
其它的功能我用到再说吧。可能写的leap版本不一样,这里的leap是DOLCE里面实现的fork版本。