Data Preprocessing for MRI Datasets
Tags: python, beginners, tutorial, career
Published: 2020-01-02 05:14:42

A lot of effort in solving any machine learning problem goes into preparing the data. In this tutorial, we will see how to load and preprocess/augment data from a non-trivial dataset. The various image format classes give full or selective access to the header (meta) information and access to the image data is made available via NumPy arrays.

To run this tutorial, please make sure the following packages are installed:
<p>
<li>scikit-image: For image io and transforms.</li>
<li>nibabel: Read / write access to some common neuroimaging file formats</li>
<li>matplotlib: which allows mathematical representations of all kinds to be created and visualized.</li></p>

 <b>Parameter</b>:
<li><b>Path</b>: A path-like object representing a file system path.</li>
<li><b>Return Type</b>: This method returns a string value that represents the directory name from the specified path.</li>
 
Download the sample nibabel files from my <a href="https://github.com/sairajes/github", style="color: red"> github </a> which is in nii.giz form 

<b>Import Libraries: </b>
```javascript
import os
import nibabel as nib
import numpy as np
import matplotlib.pyplot as plt
}
```
<b>Directory for MRI data</b>
Importing Datasets: dirName = r"file_path"

<b>function to read data from dirName</b>
```javascript
def FileRead(file_path):
    nii = nib.load(file_path)
    data = nii.get_data()
    #if (np.shape(np.shape(data))[0] == 3): #If channel data not present
     #   data = np.expand_dims(data, 3)
    return data
```
<b>function returns a 2 dimensional numpy array from a 3 dimensional data</b>
```javascript
def Nifti3Dto2D(Nifti3D):
    Nifti3DWOChannel = Nifti3D#[:,:,:,0] #Considering there is only one channel info
    Nifti2D = Nifti3DWOChannel.reshape(np.shape(Nifti3DWOChannel)[0], np.shape(Nifti3DWOChannel)[1] * np.shape(Nifti3DWOChannel)[2])
    return Nifti2D
```
 <b>function returns a 1 dimensional numpy array from a 2 dimensional array</b>
```javascript
def Nifti2Dto1D(Nifti2D):
    Nifti1D = Nifti2D.reshape(np.shape(Nifti2D)[0] * np.shape(Nifti2D)[1])
    return Nifti1D
```
<b>reshapes a 1 dimensional array to 2 dimensional data</b>
```javascript
def Nifti1Dto2D(Nifti1D, height):
    Nifti2D = Nifti1D.reshape(height,int(np.shape(Nifti1D)[0]/height))
    return Nifti2D
```
<b>reshapes 2 dimensional array to 3 dimensional data</b>
```javascript
def Nifti2Dto3D(Nifti2D):
    Nifti3DWOChannel = Nifti2D.reshape(np.shape(Nifti2D)[0],np.shape(Nifti2D)[0],np.shape(Nifti2D)[1]//np.shape(Nifti2D)[0])
    #Nifti3D = np.expand_dims(Nifti3DWOChannel, 3)
    return Nifti3DWOChannel
```
<b>normalize data between o-1</b>
```javascript
def normalize(x):
    min_val = np.min(x)
    max_val = np.max(x)
    x = (x-min_val) / (max_val-min_val)
    return x
```
<b>To copy data to local storage</b>
```javascript
def FileSave(data, file_path):
    nii = nib.Nifti1Image(data, np.eye(4))
    nib.save(nii, file_path)
```
<b>returns list of files from the given dirName</b>
```javascript
def getListOfFiles(dirName):
    # creating a list of file and sub directories 
    listOfFile = os.listdir(dirName)
    allFiles = []
# Iterate over entries
    for entry in listOfFile:
        # Creating full path
        fullPath = os.path.join(dirName, entry)
        if os.path.isdir(fullPath):
            allFiles = allFiles + getListOfFiles(fullPath)
        else:
            allFiles.append(fullPath)
    return allFiles
```
<b>Takes list of files and creates 1 dimension and 2 dimension data from MR data</b>
```javascript
def main():
    listOfFiles = getListOfFiles(dirName)
    twod_data = []# to save two dimensional data
    oned_data = []
    listOfFiles = []
    for (dirpath, dirnames, filenames) in os.walk(dirName):
        listOfFiles += [os.path.join(dirpath, file) for file in filenames]
       # listOfFiles_under.append(listOfFiles_under)
        #print(listOfFiles_under)
    for element in listOfFiles:
        print(element)
        red_files = FileRead(element)
        twod_array = Nifti3Dto2D(red_files)
        twod_data.append(twod_array)
        #print(twod_unsam)
        oned_array= Nifti2Dto1D(twod_array)
        oned_data.append(oned_array)
    oned_data = np.asarray(oned_data, dtype=np.float64, order='C')
    twod_data = np.asarray(twod_data, dtype=np.float64, order='C')
    return oned_data, twod_data

oned_data, twod_data = main()
```
<b>for visualization</b>
```javascript
data_vis = Nifti2Dto3D(Nifti1Dto2D(oned_data[0,:], 256))
#plt.imshow(data_vis[20,:,:], cmap='gray')
plt.imshow(data_vis[:,:,20], cmap='gray')
```
<b>Output for one slice image</b>
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/99po17tzfgn5kggn2hz5.png)