Python实现医学影像DICOM批量转换

现如今针对医学核磁共振MR影像的研究越来越多,但由于各种原因,从各个医院收集原始患者核磁共振影像BMP文件的难度非常大。而患者的原始DICOM文件相较MR文件更易收集,所以我们提出使用Python实现DICOM批量转换为jpg、png图像。

1.安装库

pip install numpy
pip install cv2
pip install simpleitk
pip install os

2.定义一个DICOM转JPG的函数

该函数读取图像的像素值信息,并转换为数组形式,在归一化、转换至0-255像素值区间内之后重新转换为三通道的RGB图。

# 定义dicom to jpg转换函数
def dicom2jpg(img, low_window, high_window, save_path):
    """
    :param img: dicom图像的像素值信息
    :param low_window: dicom图像像素值的最低值
    :param high_window: dicom图像像素值的最高值
    :param save_path: 新生成的jpg图片的保存路径
    :return:
    """
    oldimg = np.array([low_window * 1., high_window * 1.]) # 将像素值转换为array
    newimg = (img - oldimg[0]) / (oldimg[1] - oldimg[0]) # 将像素值归一化0-1
    newimg = (newimg * 255).astype('uint8') # 再转换至0-255,且将编码方式由原来的unit16转换为unit8
    # 将单通道转换成三通道
    img_out = np.zeros([newimg.shape[0], newimg.shape[1], 3])
    img_out[:, :, 0] = newimg
    img_out[:, :, 1] = newimg
    img_out[:, :, 2] = newimg
    # 用cv2写入图像指令,保存jpg即可
    cv2.imwrite(save_path, img_out, [int(cv2.IMWRITE_JPEG_QUALITY), 100])

3.批量转换

我们假设目标影像文件是存放在三级文件夹中,当然二级文件夹和更多级的文件夹思路相同。

我们首先需要输入影像文件存储的文件夹。

 input_root = r'C:\Users\ediso\Desktop\shizhuang\shizhuang'

 并输入想要转入的目标文件夹。

output_root = r'C:\Users\ediso\Desktop\out'

接着便可以实现DICOM文件的批量转换了。

if __name__ == '__main__':

    input_root = r'C:\Users\ediso\Desktop\shizhuang\shizhuang'
    dir_list = os.listdir(input_root)  # 打开文件夹中的图像的文件名,作为列表返回
    output_root = r'C:\Users\ediso\Desktop\out'
    if not os.path.exists(output_root):
        os.makedirs(output_root)
    # 开始遍历日期文件夹下的每个子文件夹
    print('The 1th class dir ' + str(input_root) + ' have ' + str(len(dir_list)) + ' files' + '*' * 50)
    for _dir in dir_list:
        if _dir != 'VERSION':
            dir_in1_path = os.path.join(input_root, _dir)
            dir_out1_path = os.path.join(output_root, _dir)
            if not os.path.exists(dir_out1_path):
                os.makedirs(dir_out1_path)
            dir_in2_path_list = os.listdir(dir_in1_path)
            print('The 2th class dir '+str(_dir)+' have ' + str(len(dir_in2_path_list))+' files'+'*'*50)
            # debug 使用
            j = 1
            for i in dir_in2_path_list:
                if i != 'VERSION':
                    document = os.path.join(dir_in1_path, i)
                    # countname = str(count)  # 将设置的变量数字1,转换为字符串,作为名称使用
                    countfullname = _dir + '-' +str(j) + '.jpg'
                    output_jpg_path = os.path.join(dir_out1_path, countfullname) # 设置保存每张图片的路径
                    j = j+1
                    image = sitk.ReadImage(document)
                    img_array = sitk.GetArrayFromImage(image)
                    img_array = np.squeeze(img_array, axis=0)
                    high = np.max(img_array) # 找到最大的
                    low = np.min(img_array)# 找到最小的
                    print(str(_dir)+'/'+str(i)+' have max and min pixel are:'+str(high)+' and '+str(low))
                    # 调用函数,开始转换
                    dicom2jpg(img_array, low, high, output_jpg_path)
                    # count += 1 # 为下一张图像的名称作准备,加1变成2

4.完整代码

在完整代码中,我们为了防止整个程序因为某些未知问题报错添加了一个防报错机制。

import numpy as np
import cv2
import os
import SimpleITK as sitk

# 定义dicom to jpg转换函数
def dicom2jpg(img, low_window, high_window, save_path):
    """
    :param img: dicom图像的像素值信息
    :param low_window: dicom图像像素值的最低值
    :param high_window: dicom图像像素值的最高值
    :param save_path: 新生成的jpg图片的保存路径
    :return:
    """
    oldimg = np.array([low_window * 1., high_window * 1.]) # 将像素值转换为array
    newimg = (img - oldimg[0]) / (oldimg[1] - oldimg[0]) # 将像素值归一化0-1
    newimg = (newimg * 255).astype('uint8') # 再转换至0-255,且将编码方式由原来的unit16转换为unit8
    # 将单通道转换成三通道
    img_out = np.zeros([newimg.shape[0], newimg.shape[1], 3])
    img_out[:, :, 0] = newimg
    img_out[:, :, 1] = newimg
    img_out[:, :, 2] = newimg
    # 用cv2写入图像指令,保存jpg即可
    cv2.imwrite(save_path, img_out, [int(cv2.IMWRITE_JPEG_QUALITY), 100])

if __name__ == '__main__':

    input_root = r'D:\DeepLearning\cervical\BianqueNet+\input\dicom\1'
    dir_list = os.listdir(input_root)  # 打开文件夹中的图像的文件名,作为列表返回
    output_root = r'D:\DeepLearning\cervical\BianqueNet+\input\dicom_out'
    if not os.path.exists(output_root):
        os.makedirs(output_root)
    # 开始遍历日期文件夹下的每个子文件夹
    print('The 1th class dir ' + str(input_root) + ' have ' + str(len(dir_list)) + ' files' + '*' * 50)

    for _dir in dir_list:
        try:
            if _dir != 'VERSION' and _dir != '.DS_Store':
                dir_in1_path = os.path.join(input_root, _dir)
                dir_out1_path = os.path.join(output_root, _dir)
                if not os.path.exists(dir_out1_path):
                    os.makedirs(dir_out1_path)
                dir_in2_path_list = os.listdir(dir_in1_path)
                print('The 2th class dir '+str(_dir)+' have ' + str(len(dir_in2_path_list))+' files'+'*'*50)
                # debug 使用
                j = 1
                for i in dir_in2_path_list:
                    if i != 'VERSION'and i != '.DS_Store':
                        document = os.path.join(dir_in1_path, i)
                        # countname = str(count)  # 将设置的变量数字1,转换为字符串,作为名称使用
                        countfullname = _dir + '-' +str(j) + '.jpg'
                        output_jpg_path = os.path.join(dir_out1_path, countfullname) # 设置保存每张图片的路径
                        j = j+1
                        image = sitk.ReadImage(document)
                        img_array = sitk.GetArrayFromImage(image)
                        img_array = np.squeeze(img_array, axis=0)
                        high = np.max(img_array) # 找到最大的
                        low = np.min(img_array)# 找到最小的
                        print(str(_dir)+'/'+str(i)+' have max and min pixel are:'+str(high)+' and '+str(low))
                        # 调用函数,开始转换
                        dicom2jpg(img_array, low, high, output_jpg_path)
        except Exception as e:
            print("---------------------------------------------------------the conversion of " + str(
                document) + " is failed!")
            pass
        continue

github:https://github.com/tiebro/DICOM2JPG-PNG 

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要使用Python和VTK实现CT医学影像DICOM文件的体绘制和面绘制三维重建,你可以参考以下源码: ``` python import vtk # 创建一个渲染窗口并设置交互方式 renWin = vtk.vtkRenderWindow() iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) # 读取DICOM文件 reader = vtk.vtkDICOMImageReader() reader.SetDirectoryName("path/to/dicom/files") reader.Update() # 创建体绘制的体素数据集 volumeMapper = vtk.vtkFixedPointVolumeRayCastMapper() volumeMapper.SetInputConnection(reader.GetOutputPort()) # 设置体绘制的颜色和透明度传输函数 volumeProperty = vtk.vtkVolumeProperty() volumeProperty.ShadeOn() volumeProperty.SetColor(vtk.vtkColorTransferFunction()) volumeProperty.SetScalarOpacity(vtk.vtkPiecewiseFunction()) # 创建体绘制的可视化对象 volume = vtk.vtkVolume() volume.SetMapper(volumeMapper) volume.SetProperty(volumeProperty) # 创建面绘制的等值面数据集 contourFilter = vtk.vtkMarchingCubes() contourFilter.SetInputConnection(reader.GetOutputPort()) contourFilter.SetValue(0, thresholdValue) # 设置阈值,提取等值面 # 创建面绘制的Mapper和Actor contourMapper = vtk.vtkPolyDataMapper() contourMapper.SetInputConnection(contourFilter.GetOutputPort()) contourActor = vtk.vtkActor() contourActor.SetMapper(contourMapper) # 创建渲染器和渲染窗口 renderer = vtk.vtkRenderer() renWin.AddRenderer(renderer) renderer.AddActor(volume) renderer.AddActor(contourActor) renderer.SetBackground(0, 0, 0) # 设置背景颜色为黑色 # 设置相机视角 camera = renderer.GetActiveCamera() camera.SetPosition(0, 0, -1) # 设置相机位置 camera.SetFocalPoint(0, 0, 0) # 设置焦点 camera.SetViewUp(0, -1, 0) # 设置视角 # 激活渲染器和交互操作 renderer.ResetCamera() renWin.Render() iren.Start() ``` 请注意,上述代码只提供了一个基本的框架,实际使用时需要根据具体需求进行调整。同时,你需要将代码中的"path/to/dicom/files"替换为实际的DICOM文件路径,并根据需要设置体绘制和面绘制的参数。 希望以上内容对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值