且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用python将pydicom文件(图像)分成两半?

更新时间:2023-02-21 13:45:12

一旦执行了pydicom.dcm_read(),像素数据就可以从ds.pixel_array获得.您可以只切片所需的数据,并将其保存在任何合适的库中.在此示例中,我将使用matplotlib,因为我还将使用它来验证切片是否正确.显然,根据您的需求进行调整,您需要做的一件事就是生成正确的路径/文件名以进行保存.玩得开心! (此脚本假定文件路径在paths变量中可用)

Once you have executed pydicom.dcm_read() your pixel data is available at ds.pixel_array. You can just slice the data you want and save it with any suitable library. In this example I will be using matplotlib as I also use that for verifying whether my slicing is correct. Adjust to your needs obviously, one thing you need to do is generate the correct path/filenames for saving. Have fun! (this script assumes the filepaths are available in a paths variable)

import pydicom
import matplotlib

# for testing if the slice is correct
from matplotlib import pyplot as plt

for path in paths:
    # read the dicom file
    ds = pydicom.dcmread(path)

    # find the shape of your pixel data
    shape = ds.pixel_array.shape
    # get the half of the x dimension. For the y dimension use shape[0]
    half_x = int(shape[1] / 2)

    # slice the halves
    # [first_axis, second_axis] so [:,:half_x] means slice all from first axis, slice 0 to half_x from second axis
    left_part  = ds.pixel_array[:, :half_x]
    right_part = ds.pixel_array[:,half_x:]

    # to check whether the slices are correct, matplotlib can be convenient
    # plt.imshow(left_part); do not do this in the loop

    # save the files, see the documentation for matplotlib if you want a different format
    # bmp, png are surely supported

    path_to_left_image = 'generate\the\path\and\filename\for\the\left\image.bmp'
    path_to_right_image = 'generate\the\path\and\filename\for\the\right\image.bmp'
    matplotlib.image.imsave(path_to_left_image, left_part)
    matplotlib.image.imsave(path_to_right_image, right_part)


如果要保存DICOM文件,请记住,如果不更新适当的数据,它们可能不是有效的DICOM文件.例如,从技术上说,不允许SOP实例UID与原始DICOM文件中的ID相同,也不允许与此相关的任何其他SOP实例UID.这到底有多重要,取决于您.

If you want to save the DICOM files keep in mind that they may not be valid DICOM if you do not update the appropriate data. For instance the SOP Instance UID is technically not allowed to be the same as in the original DICOM file, or any other SOP Instance UID for that matter. How important that is, is up to you.

使用下面的脚本,您可以定义命名的切片,并将在提供的路径中找到的所有dicom图像文件拆分为适当的切片.

With a script like below you can define named slices and split any dicom image file it finds in the supplied path into the appropriate slices.

import os
import pydicom
import numpy as np

def save_partials(parts, path_to_directory):
    """
    parts: list of tuples, each tuple specifying a name and a list of four slice offsets
    path_to_directory: path to directory containing dicom files
    any file with a .dcm extension will have its image data split into the specified slices and saved accordingly. 
    original file will not be modified
    """

    dir_content = [os.path.join(path_to_directory, item) for item in os.listdir(path_to_directory)]
    files = [i for i in dir_content if os.path.isfile(os.path.join(path_to_directory, i))]
    for file in files:
        root, extension = os.path.splitext(file)
        if extension.lower() != '.dcm':
            # not a .dcm file, continue with next iteration of loop
            continue
        for part in parts:
            ds = pydicom.read_file(file)
            if not isinstance(ds.pixel_array, np.ndarray):
                # no image data available
                continue
            part_name = part[0] 
            p = part[1] # slice list
            ds.PixelData = ds.pixel_array[p[0]:p[1], p[2]:p[3]].tobytes()
            ds.Rows = p[1] - p[0]
            ds.Columns = p[3] - p[2]
            ##
            ## Here you can modify any tags using ds.KeyWord
            ##
            new_file_name = "{r}-{pn}{ext}".format(r=root, pn=part_name, ext=extension)
            ds.save_as(new_file_name)
            print('saved {}'.format(new_file_name))


dir_path = '/home/wojtek/Mask'
parts = [('left', [0,512,0,256]),
         ('right', [0,512,256,512])]

save_partials(parts, dir_path)