PET图像的SUV计算

记:PET图像SUV计算方法的探索

最近项目需要,预处理有一步是从PET上计算得到SUV,开始在网上寻找相关资料,发现相当稀少,唯有水木论坛上有相关讨论,这里记一些资料和想法。

资料:
百度文库
水木论坛
维基百科(这里有计算SUV的伪代码文档)

一、SUV定义

The standardized uptake value (SUV) is the measured activity at the region of interest (ROI), which is normalized for body weight/surface area and injected dose. As a reference, if the dose were uniformly distributed over the entire body the value everywhere would be SUV ~1.0. Thus SUV is a relative uptake measure.

SUV = ROI activity(mCi/mL) * body weight(g)/injected dose(mCi)

简单来说,SUV是标准化辐射量与体重的一种方式。

二、SUV计算

1.需要的参数(从dicom获得):

PET图像的SUV计算_第1张图片

Python代码

## 获得dicom参数
from pydicom import dcmread  # 记得先pip下载

#  每个人只需要一张dicom文件
dicom_path = 'XXX.dcm'
dcm = dcmread(dicom_path)

# 获得需要的参数数据
## 几个比较特殊的
RadiopharmaceuticalInformationSequence = dcm.RadiopharmaceuticalInformationSequence[0]
RadiopharmaceuticalStartTime = str(RadiopharmaceuticalInformationSequence['RadiopharmaceuticalStartTime'].value)
RadionuclideTotalDose = str(RadiopharmaceuticalInformationSequence['RadionuclideTotalDose'].value)
RadionuclideHalfLife = str(RadiopharmaceuticalInformationSequence['RadionuclideHalfLife'].value)
##放在一起
dcm_tag = str(dcm.SeriesTime)+'\n'+str(dcm.AcquisitionTime)+'\n'+str(dcm.PatientWeight)+'\n'+RadiopharmaceuticalStartTime+'\n'
dcm_tag = dcm_tag+RadionuclideTotalDose+'\n'+RadionuclideHalfLife+'\n'+str(dcm.RescaleSlope)+'\n'+str(dcm.RescaleIntercept)

# 最后保存一个txt或者excel即可

2.SUV计算

在西门子机器上计算SUV的方法是,都是标准的DICOM Tag
(0008,0032) [100209.015000] # AcquisitionTime
(0010,1030) [75] # PatientsWeight (kg)
(0018,1072) [090000.000000] # RadiopharmaceuticalStartTime
(0018,1074) [360100006.10352] # RadionuclideTotalDose (Bq)
(0018,1075) [6586.2] # RadionuclideHalfLife (seconds)
(0028,1052) [0] # RescaleIntercept
(0028,1053) [2.3295469284058] # RescaleSlope

Given X for a pixel value, Y= (RescaleIntercept + RescaleSlope X) exp(ln2(AcqusitionTime- RadiopharmaceuticalStartTime)/ RadionuclideHalfLife)
SUV = Y/( RadionuclideTotalDose/ PatientsWeight)

需要注意的是,那个时间的格式是 小时分秒 hhmmss (0008,0032),需要进行转换

维基百科上的伪代码流程

PET图像的SUV计算_第2张图片

Python代码

def dicom_hhmmss(t):    # dicom存时间格式:小时、分钟、秒(每个占两位),这里转化回秒
    t = str(t)
    if len(t) == 5:     # 有些提取时漏了个0,小时的位置只有一位,这里把零补上
     	t = '0'+t
    h_t = float(t[0:2])
    m_t = float(t[2:4])
    s_t = float(t[4:6])
    return h_t*3600+m_t*60+s_t
    
def PET2SUV(data, PET):
    """
    :param data:PET的dicom获取的信息
    :param PET: PET的array
    :param norm: 用标准还是非标准做法
    :return: 转为SUV的array
    """
    [ST, AT, PW, RST, RTD, RHL, RS, RI] = data 		# AT基本等于ST,RI一般是0
    decay_time = dicom_hhmmss(ST)-dicom_hhmmss(RST)
    decay_dose = float(RTD) * pow(2, -float(decay_time) / float(RHL))
    SUVbwScaleFactor = (1000 * float(PW)) / decay_dose
    if norm:
        PET_SUV = (PET * float(RS) + float(RI)) * SUVbwScaleFactor    # 标准公式做法
    else:
        PET_SUV = PET * SUVbwScaleFactor    	# 非标准做法,但和软件得到的SUV较为一致
    return PET_SUV

三、一些问题与思考

1. 上述为简单计算SUV的版本,没有考虑AT与ST不同时的情况(一般是相同的)

使用上述方法获得的数据得到的结果会与医院反映的SUVmax值不同,大概是两倍。论坛有人说不用RescaleIntercept和RescaleSlope的话就会接近一些,实际我测试结果也大概如此(但还是多了一些),不过RescaleIntercept和RescaleSlope是关于图像空间的参数,影响应该不大。

2. 从公式上看,本质上SUV就是去除病人体重的干扰,可以看做是做某种程度的标准化,PET图像分析的相关文献里的预处理基本都做了这一步

但是这个转化对于后续的建模性能提升不一定有用,跑的对比实验显示转不转成SUV的结果差不多(不排除是我这是特例)。怒过有一个明显的好处就是可以让数据不需要用Float64的位数来存储,可以节省内存。

3. 目前python代码有时会遇到有的PET的DICOM信息缺失的问题,比如读取到的dcm.RadiopharmaceuticalInformationSequence 中没有RTD之类的

估计是数据扫描、存储或者下载出来时的问题,一般遇到这种特例就排除掉。

4. 读取DICOM时读取到’Private tag data’类的,导致无法获取信息,这种还不清楚怎么解决

你可能感兴趣的:(PET项目相关,图像处理相关,python,人工智能,processing)