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

本文介绍了一种使用Python的方法,通过安装相关库如numpy、cv2和simpleITK,实现从DICOM格式的医学核磁共振图像转换为jpg或png,便于数据共享和分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现如今针对医学核磁共振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 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值