Skip to main content

Library for MRI noise analysis

Project description

License: MIT example workflow Documentation Status

MRIna: A library for MRI Noise Analysis

MRIna is a library for the analysis of reconstruction noise for Modeling noise random fields generated from [ArXiv]

Lauren Hensley Partin, Daniele E. Schiavazzi and Carlos A. Sing-Long Collao

The complete set of results from the above paper can be found at this link


Installation and documentation

You can install MRIna with pip (link to PyPI)

pip install mrina

For the documentation follow this link.


What you can do with MRIna.

The MRIna library provides the following functionalities.

  • It supports the generation of k-space undersampling masks of various types including Bernoulli, variable density triangular, variable density Gaussian, variable density exponential and Halton quasi-random sequences.
  • It supports arbitrary operators that implement a forward call (eval), and inverse call (adjoint), column restriction (colRestrict), shape and norm.
  • It supports various non-linear reconstruction methods including l1-norm minimization with iterative thresholding and stagewise orthogonal matching pursuit.
  • It provides a number of scripts to generate ensembles of synthetic, subsampled and noisy k-space images (4 complex images), to reconstruct image density and velocities, and to post-process to compute error patterns, correlation, MSE and relative errors.

Single-image examples

Original image 1 Wavelet transform 1
k-space mask 1 Noisy k-space measurements 1
Reconstruction: noiseless 1 Reconstruction: CS 1
Reconstruction: CSDEB 1 Reconstruction: stOMP 1

Read grayscale image

import cv2
im = cv2.imread('city.png', cv2.IMREAD_GRAYSCALE)/255.0

Read grayscale image

from mrina import generateSamplingMask

# Select an undesampling ratio
delta = 0.25
# Generate an undersampling mask
omega = generateSamplingMask(im.shape, delta, 'bernoulli')
# Verify the undersampling ratio
nsamp = np.sum((omega == 1).ravel())/np.prod(omega.shape)
print('Included frequencies: %.1f%%' % (nsamp*100))

Read grayscale image

import pywt

waveName = 'haar'
waveMode = 'zero'
wim = pywt.coeffs_to_array(pywt.wavedec2(im, wavelet=waveName, mode=waveMode))[0]
plt.figure(figsize=(8,8))
plt.imshow(np.log(np.abs(wim)+1.0e-5), cmap='gray')
plt.axis('off')
plt.show()

Initialize a WaveletToFourier operator and generate undersampled k-space measurements

from mrina import OperatorWaveletToFourier

A = OperatorWaveletToFourier(im.shape, samplingSet=omega[0], waveletName=waveName)
yim = A.eval(wim, 1)

Noiseless recovery using l1-norm minimization

from mrina import RecoveryL1NormNoisy

# Recovery - for low values of eta it is better to use SoS-L1Ball
wimrec_cpx, _ = RecoveryL1NormNoisy(0.01, yim, A, disp=True, method='SoS-L1Ball')
# The recovered coefficients could be complex!
imrec_cpx = A.getImageFromWavelet(wimrec_cpx)
imrec = np.abs(imrec_cpx)

Generate k-space noise

# Target SNR
SNR = 50
# Signal power. The factor 2 accounts for real/imaginary parts
yim_pow = la.norm(yim.ravel()) ** 2 / (2 * yim.size)
# Noise st. dev.
sigma = np.sqrt(yim_pow / SNR)
# Noisy measurements
y = yim + sigma * (np.random.normal(size=yim.shape) + 1j * np.random.normal(size=yim.shape))

Image recovery with l1-norm minimization

# Parameter eta
eta = np.sqrt(2 * y.size) * sigma
# Recovery
wimrec_noisy_cpx, _ = RecoveryL1NormNoisy(eta, y, A, disp=True, disp_method=False, method='BPDN')
# The recovered coefficients could be complex!
imrec_noisy = np.abs(A.getImageFromWavelet(wimrec_noisy_cpx))

Estimator debiasing

# Support of noisy solution
wim_supp = np.where(np.abs(wimrec_noisy_cpx) > 1E-4 * la.norm(wimrec_noisy_cpx.ravel(), np.inf), True, False)
# Restriction of the operator
Adeb = A.colRestrict(wim_supp)
# Solve least-squares problem
lsqr = lsQR(Adeb)  
lsqr.solve(y[Adeb.samplingSet])
wimrec_noisy_cpx_deb = np.zeros(Adeb.wavShape,dtype=np.complex)
wimrec_noisy_cpx_deb[Adeb.basisSet] = lsqr.x[:]
# The recovered coefficients could be complex!
imrec_noisy_deb = np.abs(Adeb.getImageFromWavelet(wimrec_noisy_cpx_deb))

Image recovery with stOMP

from mrina import lsQR,OMPRecovery
# Recovery
wimrec_noisy_cpx, _ = OMPRecovery(A, y)
# The recovered coefficients could be complex!
imrec_noisy_cpx = A.getImageFromWavelet(wimrec_noisy_cpx)
imrec_noisy = np.abs(imrec_noisy_cpx)

Script functionalities

MRIna also provides scripts to automate:

  • the generation of noisy k-space signals.
  • linear and non-linear image reconstruction.
  • reconstructed images post-processing.

Sample generation

  python -m mrina.genSamples --fromdir $KSPACEDIR \
                             --repetitions $REALIZATIONS \
                             --origin $IMGNAME \
                             --dest $RECDIR \
                             --utype $SAMPTYPE \
                             --urate $PVAL \
                             --noisepercent $NOISEVAL

For additional information on the script input parameters, type

python -m mrina.gen_samples --help

Image recovery

  python -m mrina.recover --noisepercent $NOISEVAL \
                          --urate $PVAL \
                          --utype $SAMPTYPE \
                          --repetitions $REALIZATIONS \
                          --numprocesses $PROCESSES \
                          --fromdir $KSPACEDIR \
                          --recdir $RECDIR \
                          --maskdir $PATTERNDIR \
                          --method $SOLVERMODE \
                          --wavelet $WAVETYPE \
                          --savevels

For additional information on the script input parameters, type

python -m mrina.recover --help

Post-processing - Saving reconstructed images

  python -m mrina.saveimgs --numsamples $REALIZATIONS \
                           --maindir $MAINDIR \
                           --recdir $RECDIR \
                           --maskdir $MASKDIR \
                           --outputdir $OUTDIR \
                           --savetrue \
                           --savemask \
                           --saverec \
                           --savenoise \
                           --savelin \
                           --usetrueasref \
                           --printlevel $PRINTLEV \
                           --savelin \
                           --limits $LIMITS \
                           --fluidmaskfile $FMFILE

For additional information on the script input parameters, type

python -m mrina.saveimgs --help

Post-processing - Computing correlations

python -m mrina.correlation --numsamples $REALIZATIONS \
                             --numpts 50 \
                             --recdir ./CS/ \
                             --ptsdir ./ \
                             --vencdir ./ \
                             --maindir ./ \
                             --usefluidmask \
                             --printlevel 1

For additional information on the script input parameters, type

python -m mrina.correlation --help

Post-processing - Plot correlations

python -m mrina.plot_corr --noise 0.1 0.01 0.05 0.3 \
                         --uval 0.75 0.25 0.5 \
                         --utype vardengauss bernoulli \
                         --method cs csdebias omp \
                         --wavelet haar db8 \
                         --numsamples 100 \
                         --numpts 50 \
                         --dir ./ \
                         --outputdir ./OUT/02_corr/ \
                         --usefluidmask \
                         --printlevel 1

For additional information on the script input parameters, type

python -m mrina.plot_corr --help

Post-processing - Compute MSE and relative errors

python -m mrina.plot_mse --noise 0.1 0.01 0.05 0.3 \
                        --uval 0.75 0.25 0.5 \
                        --utype vardengauss bernoulli \
                        --method cs csdebias omp \
                        --wavelet haar db8 \
                        --numsamples 100 \
                        --numpts 50 \
                        --dir ./ \
                        --outputdir ./OUT/03_mse/ \
                        --maskdir ./ \
                        --usecompleximgs \
                        --addlinearrec \
                        --usetrueimg \
                        --usefluidmask \
                        --fluidmaskfile ia_mask.npy \
                        --printlevel 1 \
                        --percstring 1

For additional information on the script input parameters, type

python -m mrina.plot_mse --help

Core Dependencies

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mrina-0.1.2.tar.gz (139.2 kB view details)

Uploaded Source

Built Distribution

mrina-0.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

File details

Details for the file mrina-0.1.2.tar.gz.

File metadata

  • Download URL: mrina-0.1.2.tar.gz
  • Upload date:
  • Size: 139.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.27.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

File hashes

Hashes for mrina-0.1.2.tar.gz
Algorithm Hash digest
SHA256 a070765fc0a0b01cfdd091e5735eb5808841ead3f3818d42262dc6f4c2669d77
MD5 584d6fc0f41ccfb4572a5605bd9d9443
BLAKE2b-256 52b788a695e6a19b983202173fc0bb307ebfa551b08920f90539bfa8f2b3c1f5

See more details on using hashes here.

File details

Details for the file mrina-0.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for mrina-0.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ef06a2e368332abe5a084b2c195688ced1150ffa3993964b815f4555811db2ec
MD5 b910c96d866d910c84349b8fcb3aa0e7
BLAKE2b-256 585174088b96de9a299e6812c09677117877100a900452723a2a325e9edc53d9

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page