Search code examples
numpymedicalpydicommedical-imaging

Converting DICOM image to numpy array of shape (s, 3, 256, 256)


I've got folders with MRI images in them and I'm trying to replicate the MRnet study with my own data. Their model works on 1 .npy file per subject, shape (s, 3, 256, 256), with s being number of slices for a given subject (varies between subjects).

I've looked at several different methods of solving this but none seems to work for me. Closest I have gotten was to at least convert the .dcm files to JPEG using:

import pydicom
import os
import numpy as np
import cv2
dicom_folder = 'C:/Users/GlaDOS/PythonProjects/dicomnpy/DICOMFILES/sub1/' # Set the folder of your dicom files that inclued images 
jpg_folder = 'C:/Users/GlaDOS/PythonProjects/dicomnpy/DICOMFILES/jpg' # Set the folder of your output folder for jpg files 
# Step 1. prepare your input(.dcm) and output(.jpg) filepath 
dcm_jpg_map = {}
for dicom_f in os.listdir(dicom_folder):
    dicom_filepath = os.path.join(dicom_folder, dicom_f)
    jpg_f = dicom_f.replace('.dcm', '.jpg') 
    jpg_filepath = os.path.join(jpg_folder,jpg_f)
    dcm_jpg_map[dicom_filepath] = jpg_filepath

# Now, dcm_jpg_map is key,value pair of input dcm filepath and output jpg filepath

# Step 2. process your image by input/output information
for dicom_filepath, jpg_filepath in dcm_jpg_map.items():
    # convert dicom file into jpg file
    dicom = pydicom.read_file(dicom_filepath)
    np_pixel_array = dicom.pixel_array
    cv2.imwrite(jpg_filepath, np_pixel_array)

I know that I can use pydicom to do this, but I can't find any information in their documentation on how to achieve this result.

I essentially want the information in np_pixel_array of the above code, which returns a shape of 256, 216, however I want every dcm file in the folder in that array so it would become (30, 256, 216) or however many slices each folder has.

Does anyone have experience with this and may be able to help?


Solution

  • you could modify this section of your code:

    for dicom_filepath, jpg_filepath in dcm_jpg_map.items():
        # convert dicom file into jpg file
        dicom = pydicom.read_file(dicom_filepath)
        np_pixel_array = dicom.pixel_array
        cv2.imwrite(jpg_filepath, np_pixel_array)
    

    to this:

    unstacked_list = []
    for dicom_filepath, jpg_filepath in dcm_jpg_map.items():
        # convert dicom file into jpg file
        dicom = pydicom.read_file(dicom_filepath)
        np_pixel_array = dicom.pixel_array
        unstacked_list.append(np_pixel_array)
        cv2.imwrite(jpg_filepath, np_pixel_array)
    final_array = np.array(unstacked_list)
    

    an example of how this works is below with a simpler scenario, imagine arrays a, b and c are the np_pixel_array arrays and final_array is the format you wanted

    import numpy as np
    unstacked_list = []
    
    a = np.array([[1,2], [3,4]])
    b = np.array([[5,6], [7,8]])
    c = np.array([[9,10], [11,12]])
    
    for i in [a, b, c]:
        unstacked_list.append(i)
    final_array = np.array(unstacked_list)
    
    print(final_array.shape)
    print(f'shape of final_array is {shape}')
    print('')
    print(f'final array is{final_array}')
    
    

    output is

    shape of final_array is (3, 2, 2)
    
    
    final array is
    
    [[[ 1  2]
      [ 3  4]]
    
     [[ 5  6]
      [ 7  8]]
    
     [[ 9 10]
      [11 12]]]