处理.dcm图像别转换成.nii文件了(阿巴阿巴我不太理解我得到的nii的值)

项目场景:

做一个3D图像分类。有很多的图像切片,图像是.dcm格式的。
我尝试过把它转换成jpg格式,但是感觉不太整洁,就把它们预处理后都变成.nii格式。每次读取一个.nii文件,非常整洁。


问题描述

我之前看过.dcm文件,它的值在0-2300。用下面这个代码去看,RescaleSlope是1.0,RescaleIntercept是-1024。转换成Hu值的话,原来的值*RescaleSlope+RescaleIntercept。HU值大概在-1000-+1000。
我之前转换成.nii文件,一直没有看它文件读取出来的值,觉得都是cong.dcm中读取出来直接保存的没什么问题。后来我读取了.nii文件里面的最大值和最小值-2000-1500多,我不知道数据类型,对这个值怎么来的也不知道,想半天也没想明白。(可能.nii.gz的精度太低了?不理解)

就不要用下面代码

import os
import nibabel as nib
import dicom2nifti


import SimpleITK as sitk

def dcm2nii(path_read, path_save):
    # 获取DICOM文件列表
    series_file_names = []  # 存储DICOM文件路径的列表

    for dir_name, _, file_names in os.walk(path_read):
        for file_name in file_names:
            if file_name.endswith('.dcm'):
                series_file_names.append(os.path.join(dir_name, file_name))

    # 读取DICOM文件
    reader = sitk.ImageSeriesReader()
    reader.SetFileNames(series_file_names)
    image = reader.Execute()
    
    sitk.WriteImage(image, path_save)

path_read = r"xx"
path_save = r"xx"
dcm2nii(path_read,path_save)

解决:

下面这个是获取HU值的代码:

def read_dicom_and_get_hu_value(dicom_file_path,max=500,min=0):#max,min是你要看的部位最清晰的时候的HU值,我这个是胃部的300-500,30-50之间,我就取了个0-500
    try:
        # 读取DICOM文件
        dcm = pydicom.dcmread(dicom_file_path, force=True)
        dcm.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian

        # 检查是否包含HU值信息
        if 'PixelData' in dcm:
            # 获取HU值
            hu_values = dcm.pixel_array.astype(np.float32) * float(dcm.RescaleSlope) + float(dcm.RescaleIntercept)#float64
            hu_values = np.expand_dims(hu_values, axis=0)
            hu_values[hu_values < min] = min
            hu_values[hu_values > max] = max

            return hu_values
        else:
            print("DICOM文件不包含像素数据,无法获取HU值。")
            return None
    except Exception as e:
        print(f"读取DICOM文件时发生错误:{str(e)}")
        return None

下面这个是改变形状的代码,在totensor之前用。

def resize_volume(img):
    """Resize across z-axis"""
    # Set the desired depth
    desired_depth = 64#你输入网络的长宽高
    desired_width = 128
    desired_height = 128
    # Get current depth
    current_channel = img.shape[0]
    current_depth = img.shape[1]#这个看自己输出吧,我是和上面代码配套的,就是要是上面你没有增加维度只有0,1,2,就找好自己数据的长宽高。
    current_width = img.shape[2]
    current_height = img.shape[3]
    # Compute depth factor
    depth = current_depth / desired_depth
    width = current_width / desired_width
    height = current_height / desired_height
    depth_factor = 1 / depth
    width_factor = 1 / width
    height_factor = 1 / height
    # Resize across z-axis
    img = ndimage.zoom(img, (1,depth_factor,width_factor, height_factor), order=1)
    return img

这次是用的自己的数据集,或者是别人给的,就得自己写读取文件的代码。

不放代码了,简单说一下自己对读取数据的理解。

#读取DICOM文件并读取HU值
class DicomFolder(data.Dataset):
    def __init__(self, root_dir, json_path,xls_path,  image_size=(128,128,64), mode='train'):#有个json文件能够区分训练,验证测试。这里的xls文件是标了每个病例的结局
    """
    下面就一堆代码,但是主要是弄清楚自己训练集,测试集,验证集数据在哪,标签在哪。
    把它们的路径存放到list中,getitem中会使用
    """
       

    def __getitem__(self, index):#希望data_list只存储那个编号
        """
        根据上面得到的列表读取数据,然后对数据进行预处理,比如计算HU值,改变大小。
        然后输出。
        有时候也可以做一些数据增强。
        分割中要是图片旋转,标签也要旋转。
        分类中标签是0,1。
        """
        return stacked_tensor,class_num
    def __len__(self):
    	"""
    	这个里面就下面这行代码,这个是多少它一个epoch读取的就是多少。
    	所以下面这个list得代表着训练集、验证集、测试集得长度。
    	训练的时候一个epoch要多少个数据。
    	"""
        return len(self.data_list)

你可能感兴趣的:(python,数据分析,深度学习)