DCM图像和Nil图像的差异
- '.dcm’图像是二维CT图像,很多张图像组合在一起是一个病人的横截面扫描。所以一般一个病人就是一个PAT0i文件夹,里面有很多张.dcm图像。
- nil图像是三维的,一个文件里面直接包含了一个病人所有层的扫描图像。
DCM图像的读取
import numpy as np
import pydicom
src = './CT_scans 01/PAT003/D0107.dcm'
my_dcm = pydicom.dcmread(src)
读取出来很多信息,具体描述如下:
DCM图像的信息
我们需要用于图像处理的主要有五个信息:
info18,info19,info20-22 。(其中info22最重要,其代表CT图像的像素。)
下面从图像中获取五种信息,注意pixel_array是获取一个二维像素矩阵,将来存png或者jpg图片到本地就用到了这个矩阵。不要写成PixelData,那个不是我们需要的
info18 = my_dcm.WindowCenter
info19 = my_dcm.WindowWidth
info20 = my_dcm.RescaleIntercept
info21 = my_dcm.RescaleSlope
info22 = my_dcm.pixel_array
用info20-22可以算出CT值,单位是HU:
CT = info21 * info22 + info20
print(CT)
print(CT.shape)
print(np.max(CT))
print(np.min(CT))
窗宽和窗位
先推荐一个很好的讲CT窗位和窗宽的视频,是一个kaggle大佬推荐的:https://www.youtube.com/watch?v=KZld-5W99cI
窗位和窗宽我们前面已经读取出来了,即info18和info19。
先不管这两个值,我们直接将前面算出来的CT值先用plt画出灰度图:
import matplotlib.pyplot as plt
plt.figure(figsize=(10,10))
plt.axis('off')
plt.imshow(CT,'gray')
plt.show()
如果你试了的话,会发现此时的图像效果不好,因此我们需要使用info18,info19的窗宽和窗位对图像增强。
注意:info18,info19的值是初始就存在于dcm文件中的,这是扫描仪给我们提供的建议值,我们直接使用他提供的建议值来修改我们原始的CT图像。
建议观看值的区间计算方法: [ 窗位 - 窗宽 / 2, 窗位 + 窗宽 / 2 ]
CT_min = info18 - info19/2
CT_max = info18 + info19/2
CT2 = np.clip(CT,CT_min,CT_max) # 小于min的都等于min,大于max的都等于max
plt.figure(figsize=(7.12,7.12)) # 适配屏幕
plt.axis('off')
plt.imshow(CT2,'gray')
plt.show()
改完以后再试试画一下CT图,会发现被加强了,更容易被网络训练了。
存储修改窗位和窗宽的图片
我试了两种存储方式:
- plt.savefig()
- cv2.imwrite()
这里推荐用后者存储图片,整体代码如下:
# 读取原始dcm图像
ds = pydicom.dcmread(’dcm文件路径‘)
info20 = ds.RescaleIntercept
info21 = int(ds.RescaleSlope)
info22 = ds.pixel_array
CT = info21 * info22 + info20
info18 = ds.WindowCenter
info19 = ds.WindowWidth
CT_min = info18 - info19/2
CT_max = info18 + info19/2
CT = np.clip(CT,CT_min,CT_max)
ct_image = to255(CT) # 归一化
cv2.imwrite(保存路径+文件名.png, ct_image)
归一化代码如下:
def to255(img): # 归一化到0-255代码
min_val = img.min()
max_val = img.max()
img = (img - min_val) / (max_val - min_val + 1e-5) # 图像归一化
img = img * 255 # *255
return img
参考:
https://www.youtube.com/watch?v=KZld-5W99cI