Search code examples
pythonmatlabnumpyscipydicom

How to read a saved three-dimensional matrix (Dicom Matrix) of Matlab as Python syntax in Python?


I have saved a 3D matrix with coordinate (row = 288, col = 288, slice(z) =266) in Matlab.
Now I want to load it in Python. Unfortunately, after loading, it is as (row = 288, col = 266, slice(z) =288) in Python.
Given that, Matlab syntax for size: (rows, columns, slices in 3rd dimension) and Python syntax for size: (slices in 3rd dim, rows, columns).

For example, in the following code, when I want to viwe the variable A as an array it is as (row = 288, col = 266, slice(z) =288):

from math import sqrt
from skimage import data
import matplotlib.pyplot as plt
import cv2
import pydicom
import scipy.io as sio
import os
import numpy as np


for root, dirs, files in 
os.walk('G:\PCodes\Other_Codes'):
    matfiles = [_ for _ in files if _.endswith('.mat')]
    for matfile in matfiles: # matfile: 'Final_Volume.mat'
        Patient_All_Info = sio.loadmat(os.path.join(root, matfile)) # Patient_All_Info : {dict}


Patient_All_Info.items()
A = Patient_All_Info["Final_Volume"] # A: {ndarray} : (288, 266, 288) - it isn't as (row = 288, col = 288, slice(z) =266) coordinates.
S = np.shape(A) # S: <class 'tuple'>: (288, 288, 266)  ?

dcm_image = pydicom.read_file('A')
image = dcm_image.pixel_array
plt.imshow(image, cmap='gray')
plt.show()

How to load a saved 3D matrix (Dicom Matrix) of Matlab in Python?


Solution

  • In an Octave session:

    >> x = reshape(1:24,4,3,2);
    >> save -v7 'test.mat' x
    

    With Python, loadmat retains the shape and F order:

    In [200]: data = loadmat('test.mat')
    In [208]: data['x'].shape
    Out[208]: (4, 3, 2)
    In [209]: data['x'].ravel(order='F')
    Out[209]: 
    array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13.,
           14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24.])
    

    Transpose will produce a (2,3,4) array

    In [210]: data['x'].T
    Out[210]: 
    array([[[ 1.,  2.,  3.,  4.],
            [ 5.,  6.,  7.,  8.],
            [ 9., 10., 11., 12.]],
    
           [[13., 14., 15., 16.],
            [17., 18., 19., 20.],
            [21., 22., 23., 24.]]])
    

    transpose can take an order parameter, eg data['x'].transpose(2,0,1).

    (I'm not familiar with dicom, but hopefully this illustrates how loadmat handles a 3d array from MATLAB.)