5. Image Registration
DRSuite processing assumes that the multicontrast MRI images are properly coregistered. If they are not coregistered, then DRSuite’s registration tool can be used to align them. However, it should be noted that it is always better if the images were closely aligned at the time of data acquisition, since registration can cause a loss in spatial resolution, among other issues.
5.1. Overview
The DR-CSI Registration module provides robust nonlinear registration capabilities specifically designed for spectral MRI data. Registration is a critical preprocessing step that aligns multiple spectral volumes to correct for motion artifacts and ensure spatial consistency across the spectral dimension. This tool employs a multi-stage registration pipeline combining center alignment, affine registration, and nonlinear deformable registration using GPU-accelerated PyTorch/MONAI implementations.
5.1.1. Why Registration is Important
Spectral MRI data consists of multiple 3D volumes acquired at different spectral points (e.g., diffusion or relaxation weightings). Patient motion, physiological movements, and scanner instabilities can cause misalignment between these volumes, leading to:
Spatial inconsistencies across spectral dimensions
Artifacts in downstream spectral analysis
Reduced accuracy in quantitative parameter estimation
Loss of fine structural details
The registration tool corrects these misalignments by:
Center alignment: Initial coarse alignment based on image centers
Affine registration: Global linear transformation (rotation, translation, scaling)
Nonlinear registration: Local deformable warping to account for tissue deformation
5.1.2. Registration Pipeline Architecture
Input .mat file → NIfTI conversion → Registration → .mat reconstruction
↓ ↓ ↓ ↓
spectral_data spectral_point_*.nii.gz *.reg.nii.gz registered.mat
The pipeline consists of three main components:
Data Conversion: Spectral .mat format → Individual NIfTI volumes
Registration: Multi-stage alignment with GPU acceleration
Reconstruction: Registered NIfTI → Spectral .mat format
5.2. Command-Line Interface
5.2.1. Complete Automated Workflow (Recommended)
For most users, the integrated module workflow provides the simplest interface:
Shell Script:
python run_registration_module.py <input_mat_file> <output_directory> [--processes <num>]
Example:
python run_registration_module.py data/patient_data.mat results/patient_registered
MATLAB (via system call):
system('python run_registration_module.py data/patient_data.mat results/patient_registered');
5.2.2. Step-by-Step Workflow
For users who need more control over individual steps:
Step 1: Convert .mat to NIfTI
python convert_mat_to_nifti.py <input_mat_file> <output_directory> [--res X Y Z]
Step 2: Register NIfTI files
python register_nifti.py <input_directory> <output_directory> [--processes <num>] [--template <template_file>]
Step 3: Convert back to .mat
python convert_nifti_to_mat.py <input_directory> <output_mat_file> <original_mat_file>
5.3. Required Inputs
5.3.1. input_mat_file
Filename of the .mat file storing spectral MRI data. The file must contain:
data: 4D numpy array with shape(z, y, x, spectral_points)Spatial dimensions:
(z, y, x)represent the 3D MR volumeSpectral dimension: Last axis contains multiple spectral acquisitions
Data type: Typically
uint16orfloat64
resolution(optional but recommended): Array[[x_res, y_res, z_res]]in millimetersExample:
[[2.3, 2.3, 5.0]]for 2.3mm × 2.3mm × 5mm voxelsIf not provided, default resolution
[1.0, 1.0, 1.0]is used
Example .mat file structure:
{
'data': np.array(shape=(12, 52, 104, 31), dtype=np.uint16),
'resolution': np.array([[2.3, 2.3, 5.0]]),
'transform': np.eye(4),
'spatial_dim': np.array([[12, 52, 104]])
}
File format details: See File Formats
5.3.2. output_directory
A string specifying the directory where output files will be saved. The directory structure will be:
output_directory/
├── nifti/ # Converted NIfTI files
│ ├── spectral_point_000.nii.gz
│ ├── spectral_point_001.nii.gz
│ └── ...
├── registration/ # Registered NIfTI files
│ ├── spectral_point_000.reg.nii.gz
│ ├── spectral_point_001.reg.nii.gz
│ ├── ...
│ └── registration_metadata.txt
└── {input_name}_registered.mat # Final registered data
5.4. Optional Inputs
5.4.1. --processes <num> (or -p <num>)
Number of parallel processes for registration. Default: 4
Higher values (8-16): Faster processing on multi-core systems, but requires more RAM
Lower values (1-4): More memory-efficient, suitable for limited resources
Single process (
1): Sequential processing, minimal overhead, useful for debugging
Example:
python run_registration_module.py data/input.mat output/ --processes 8
Note: GPU usage is per-process. Multiple processes share GPU resources.
5.4.2. --template <template_file> (Registration Step Only)
Specify a custom template/reference image for registration. By default, the pipeline uses template generation strategies:
Default: Average template (average of all spectral volumes)
Alternative: Central volume (middle spectral point)
Custom: User-specified NIfTI file
Example with custom template:
python register_nifti.py input_nifti/ output_nifti/ --template input_nifti/spectral_point_015.nii.gz
5.4.3. --template-strategy <strategy>
Choose automatic template selection strategy:
average: Compute average volume from all spectral points (default, best SNR)central: Use middle spectral volumespecified: Requires--templatewith specific file
Example:
python register_nifti.py input_nifti/ output_nifti/ --template-strategy central
5.4.4. --res X Y Z (Conversion Step Only)
Override voxel resolution when converting .mat to NIfTI. Specified in millimeters as three space-separated values.
Example:
python convert_mat_to_nifti.py input.mat output/ --res 2.0 2.0 3.0
If not specified, resolution is read from the .mat file’s resolution field.
5.5. Output
The registration pipeline produces multiple output files organized in a structured directory:
5.5.1. 1. Intermediate NIfTI Files
Location: <output_directory>/nifti/
Individual NIfTI volumes for each spectral point:
Filenames:
spectral_point_000.nii.gz,spectral_point_001.nii.gz, …,spectral_point_N.nii.gzFormat: Compressed NIfTI (
.nii.gz)Content: 3D spatial volume for each spectral acquisition
Metadata: Preserved affine transformation, spacing, and orientation
Metadata file: spectral_metadata.txt contains, (e.g.):
Data from spectral format .mat file
Original data shape: (12, 52, 104, 31)
Spectral dimension: 31 (last dimension)
Spatial dimensions: (12, 52, 104) (x, y, z)
Resolution: [[2.3 2.3 5.0]]
Number of NIfTI files created: 31
Spacing used: [2.3, 2.3, 5.0]
5.5.2. 2. Registered NIfTI Files
Location: <output_directory>/registration/
Registered volumes aligned to the template:
Filenames:
spectral_point_000.reg.nii.gz,spectral_point_001.reg.nii.gz, …Format: Compressed NIfTI (
.nii.gz)Content: Spatially aligned 3D volumes
Transformations: Composed affine + nonlinear deformation fields
Registration metadata: registration_metadata.txt contains (e.g.):
Registration completed: 2025-11-16 14:23:45
Template strategy: average
Number of volumes: 31
Successful registrations: 31
Failed registrations: 0
Processing time: 3.7 hours
GPU device: NVIDIA RTX 3090
Deformation fields (optional, saved in subdirectories):
spectral_point_XXX.rodreg.*/composed_ddf.map.nii.gz: Composed forward deformationspectral_point_XXX.rodreg.*/inv.composed_ddf.map.nii.gz: Inverse deformation
5.5.3. 3. Final Registered .mat File
Location: <output_directory>/<input_name>_registered.mat
Reconstructed spectral data in HDF5-based MATLAB v7.3 format:
Variables:
data: 4D array, shape(z, y, x, num_spectral), same dtype as inputExample:
(12, 52, 104, 31)with dtypeuint16All spectral volumes aligned to common spatial reference
resolution: Array[[x_res, y_res, z_res]], preserved or derived from NIfTI spacingtransform: 4×4 affine matrix (preserved from original file)spatial_dim: Array[[x_dim, y_dim, z_dim]](preserved from original file)
5.5.4. 4. Visualization Files (Optional)
Location: <output_directory>/nifti/
PNG preview images for quality assessment:
spectral_point_000.png,spectral_point_001.png, …,spectral_point_004.pngOrthogonal slice views (axial, sagittal, coronal)
Generated for first 5 spectral points only
5.6. Example Usage
5.6.1. Example 1: Basic Registration Workflow
Complete automated processing of patient data:
# Input: data/patient001.mat with 31 spectral points
# Output: results/patient001/
python run_registration_module.py data/patient001.mat results/patient001
Expected output:
Step 1: Converting .mat to NIfTI format...
✅ Created 31 spectral NIfTI files
Step 2: Registering spectral volumes...
🔧 Using GPU 0 for registration
✅ Registration completed: 31/31 successful
Processing time: 3.2 hours
Step 3: Converting back to .mat format...
✅ Saved: results/patient001/patient001_registered.mat
Final data shape: (12, 52, 104, 31)
5.6.2. Example 2: Custom Resolution and Parallel Processing
Override resolution and use 8 parallel processes:
# Step 1: Convert with custom resolution
python convert_mat_to_nifti.py data/scan_data.mat temp/nifti_out --res 1.5 1.5 3.0
# Step 2: Register with 8 parallel processes
python register_nifti.py temp/nifti_out temp/registered --processes 8
# Step 3: Reconstruct with metadata preservation
python convert_nifti_to_mat.py temp/registered results/scan_registered.mat data/scan_data.mat
5.6.3. Example 3: Custom Template Registration
Use a specific high-quality volume as registration template:
# First, inspect volumes and identify best quality (e.g., spectral_point_020)
python convert_mat_to_nifti.py data/input.mat temp/nifti
# Register using volume 20 as template
python register_nifti.py temp/nifti temp/registered \
--template temp/nifti/spectral_point_020.nii.gz \
--processes 4
# Reconstruct
python convert_nifti_to_mat.py temp/registered results/output.mat data/input.mat
5.6.4. Example 4: MATLAB Integration
Call the registration module from MATLAB:
% Set paths
input_file = 'data/mri_data.mat';
output_dir = 'results/registered_output';
% Run registration module
cmd = sprintf('python run_registration_module.py %s %s --processes 4', ...
input_file, output_dir);
[status, output] = system(cmd);
% Check status
if status == 0
fprintf('Registration completed successfully\n');
% Load registered data
registered_file = fullfile(output_dir, 'mri_data_registered.mat');
data = load(registered_file);
fprintf('Registered data shape: %s\n', mat2str(size(data.data)));
else
fprintf('Registration failed:\n%s\n', output);
end
5.7. Processing Time and Hardware Requirements
5.7.1. Hardware Requirements
Minimum Requirements:
CPU: Multi-core processor (4+ cores recommended)
RAM: 16 GB
GPU: NVIDIA GPU with CUDA support (e.g., GTX 1060 or better)
GPU Memory: 4 GB minimum
Disk Space: 5-10 GB for temporary files
Recommended Configuration:
CPU: 8+ cores (Intel i7/i9, AMD Ryzen 7/9)
RAM: 32 GB
GPU: NVIDIA RTX 3060 or better (8+ GB VRAM)
Disk: SSD for faster I/O
5.7.2. Processing Time Estimates
Typical processing times for a dataset with 31 spectral volumes (spatial dimensions: 12×52×104):
Component |
Time (GPU) |
Time (CPU-only) |
|---|---|---|
.mat → NIfTI conversion |
30 sec |
30 sec |
Registration (4 processes) |
3-4 hours |
12-24 hours |
NIfTI → .mat conversion |
1 min |
1 min |
Total |
~3.5 hours |
~12-24 hours |
Factors affecting processing time:
Number of spectral volumes (scales linearly)
Spatial resolution (higher resolution = longer time)
Number of registration iterations (default: 1500 affine + 5000 nonlinear)
GPU performance (RTX 3090 ~2× faster than GTX 1060)
Parallel processes (4-8 optimal for most systems)
5.8. Technical Notes
5.8.1. Registration Algorithm Details
The registration pipeline implements a three-stage approach:
Center Alignment (SimpleITK):
Computes center of mass for fixed and moving images
Applies translation to align centers
Fast initialization step (~1 second per volume)
Affine Registration (PyTorch/MONAI):
12-parameter affine transformation (translation, rotation, scaling, shearing)
Adam optimizer with learning rate 0.01
1500 iterations (default)
Local normalized cross-correlation (LNCC) similarity metric
GPU-accelerated gradient computation
Nonlinear Registration (PyTorch/MONAI):
Dense deformation field (U-Net architecture)
5000 iterations (default)
LNCC similarity + smoothness regularization
Diffeomorphic (topology-preserving) transformations
GPU-accelerated warping and interpolation
5.8.2. Template Selection Strategies
Average Template (Default):
# Pseudo-code for average template generation
template = np.mean([load_volume(f) for f in all_volumes], axis=0)
Advantages: Best signal-to-noise ratio, balanced representation
Disadvantages: Slightly blurred if volumes are already misaligned
Best for: Most clinical datasets
Central Volume:
# Pseudo-code for central volume selection
n_volumes = len(all_volumes)
template = load_volume(all_volumes[n_volumes // 2])
Advantages: Fast, real acquired volume (no averaging artifacts)
Disadvantages: May not be optimal reference for all volumes
Best for: High-quality datasets with minimal motion
5.9. Troubleshooting
5.9.1. Common Issues and Solutions
Issue 1: “CUDA out of memory” error
Cause: GPU memory insufficient for volume size or too many parallel processes
Solutions:
Reduce number of processes:
--processes 2Use smaller batch size (modify
src/warper.pyif needed)Upgrade GPU or use system with more VRAM
Issue 2: “No CUDA-capable device detected”
Cause: No NVIDIA GPU or CUDA drivers not installed
Solutions:
Install CUDA toolkit and drivers
Check with:
python -c "import torch; print(torch.cuda.is_available())"Registration will fallback to CPU (much slower)
Issue 3: Registration takes too long (>6 hours)
Cause: CPU-only processing or insufficient GPU resources
Solutions:
Verify GPU usage:
nvidia-smishould show Python processIncrease parallel processes if you have idle CPU cores
Consider reducing registration iterations for faster (but less accurate) results
Issue 4: “Unable to open file (file signature not found)” HDF5 error
Cause: Attempting to read non-HDF5 file with h5py
Solutions:
Delete any partial output files
Ensure original .mat file is valid:
python -c "import scipy.io; scipy.io.loadmat('file.mat')"Re-run the complete workflow
Issue 5: Poor registration quality
Causes: Poor template selection, insufficient iterations, or extreme motion
Solutions:
Try different template strategies (
average,central, or specify best volume)Increase registration iterations in
src/registration.pyCheck input data quality (SNR, artifacts)
Visual inspection: review PNG previews in
nifti/directory
5.10. Performance Optimization Tips
Optimal parallel processes:
Start with
--processes 4Monitor CPU/GPU usage with
htopandnvidia-smiIncrease if resources underutilized, decrease if memory issues
Fast preliminary testing:
Reduce iterations in
src/registration.pyfor quick testsUse subset of data (manually select few spectral points)
Restore full iterations for final processing
Storage optimization:
Use SSD for intermediate NIfTI files
Clean up intermediate directories after successful completion
Compressed NIfTI (
.nii.gz) saves 70-90% disk space
GPU selection (multi-GPU systems):
Set
CUDA_VISIBLE_DEVICES=0for first GPUDistribute processes across GPUs:
CUDA_VISIBLE_DEVICES=0,1