example images and qc run
import siq
## Failed to import duecredit due to No module named 'duecredit'
## /Users/stnava/Library/Python/3.9/lib/python/site-packages/bids/grabbids/__init__.py:6: FutureWarning:
##
## grabbids has been renamed to layout in version 0.6.5, and will be removed in version 0.8
import ants
import antspynet
import antspymm
eximg = siq.simulate_image( )
ants.plot( eximg, nslices=8, ncol=4 )
exfn0 = '/tmp/project-sid-date-T1w-uid.nii.gz'
ants.image_write( eximg, exfn0 )
qc = antspymm.blind_image_assessment( exfn0 )
qc2 = antspymm.blind_image_assessment( eximg )
print( qc.keys() )
## Index(['fn', 'noise', 'snr', 'cnr', 'psnr', 'ssim', 'mi', 'reflection_err',
## 'EVR', 'msk_vol', 'spc0', 'spc1', 'spc2', 'org0', 'org1', 'org2',
## 'dimx', 'dimy', 'dimz', 'slice', 'modality', 'mriseries', 'mrimfg',
## 'mrimodel'],
## dtype='object')
exfns = [ exfn0 ]
simulated images with high noise and high smoothing
# gaussian noise
exfnroot = '/tmp/project-sid-date-T1w-'
nzimg = siq.simulate_image( ).add_noise_to_image( 'additivegaussian', [0,1] )
exfn = exfnroot+'gaussiannoise.nii.gz'
ants.image_write( nzimg, exfn )
exfns.append( exfn )
ants.plot( nzimg )
# salt+pepper
nzimg2 = siq.simulate_image( )
nzimg2 = ants.add_noise_to_image( nzimg2, 'saltandpepper', [0.2,-1,1] )
exfn = exfnroot+'saltpepper.nii.gz'
ants.image_write( nzimg2, exfn )
exfns.append( exfn )
ants.plot( nzimg2 )
# smooth
smimg = siq.simulate_image( ).smooth_image( 3 )
exfn = exfnroot+'smooth.nii.gz'
ants.image_write( smimg, exfn )
exfns.append( exfn )
ants.plot( smimg )
# time series
tsimg = siq.simulate_image( [16,16,16,4] )
exfn = exfnroot+'timeseries.nii.gz'
ants.image_write( tsimg, exfn )
exfns.append( exfn )
qc on all these
import pandas as pd
qcdf = pd.DataFrame()
for k in range(len(exfns)):
myqc = antspymm.blind_image_assessment( exfns[k] )
qcdf = pd.concat( [ qcdf, myqc ], axis=0 )
## /Users/stnava/Library/Python/3.9/lib/python/site-packages/antspymm/mm.py:6968: RuntimeWarning:
##
## divide by zero encountered in float_scalars
##
## /Users/stnava/Library/Python/3.9/lib/python/site-packages/antspymm/mm.py:6969: RuntimeWarning:
##
## divide by zero encountered in float_scalars
##
## /Users/stnava/Library/Python/3.9/lib/python/site-packages/antspymm/mm.py:6968: RuntimeWarning:
##
## divide by zero encountered in float_scalars
##
## /Users/stnava/Library/Python/3.9/lib/python/site-packages/antspymm/mm.py:6969: RuntimeWarning:
##
## divide by zero encountered in float_scalars
##
## /Users/stnava/Library/Python/3.9/lib/python/site-packages/antspymm/mm.py:6968: RuntimeWarning:
##
## divide by zero encountered in float_scalars
##
## /Users/stnava/Library/Python/3.9/lib/python/site-packages/antspymm/mm.py:6969: RuntimeWarning:
##
## divide by zero encountered in float_scalars
qcdf.to_csv("/tmp/qc.csv")
qc = read.csv( "/tmp/qc.csv" )[,-1]
DT::datatable( qc )
# knitr::kable( qc, caption='qc data frame')
fn | noise | snr | cnr | psnr | ssim |
---|---|---|---|---|---|
project-sid-date-T1w-uid | 0.01206 | 7.756 | 5.724 | 22.57 | 0.9311 |
project-sid-date-T1w-gaussiannoise | 0.1096 | 7.883 | 7.191 | 15.19 | 0.6257 |
project-sid-date-T1w-saltpepper | 0.08407 | 5.394 | 4.17 | 12.44 | 0.481 |
project-sid-date-T1w-smooth | 0.02173 | 11.07 | 9.264 | 26.48 | 0.9736 |
project-sid-date-T1w-timeseries | 0.09481 | 10.22 | 8.452 | 20.15 | 0.9104 |
project-sid-date-T1w-timeseries | 0.09979 | Inf | Inf | 21.94 | 0.9539 |
project-sid-date-T1w-timeseries | 0.07932 | Inf | Inf | 22.18 | 0.9568 |
project-sid-date-T1w-timeseries | 0.07959 | Inf | Inf | 19.28 | 0.9099 |
mi | reflection_err | EVR | msk_vol | spc0 | spc1 | spc2 | org0 | org1 |
---|---|---|---|---|---|---|---|---|
-1.022 | 0.1658 | 0.7168 | 25817 | 1 | 1 | 1 | 0 | 0 |
-0.2572 | 0.2096 | 0.8457 | 32756 | 1 | 1 | 1 | 0 | 0 |
-0.6729 | 0.2433 | 0.8379 | 32733 | 1 | 1 | 1 | 0 | 0 |
-1.846 | 0.2916 | 0.0332 | 29081 | 1 | 1 | 1 | 0 | 0 |
-0.9372 | 0.2214 | 0.5955 | 3976 | 1 | 1 | 1 | 0 | 0 |
-1.164 | 0.2219 | 0.5882 | 4080 | 1 | 1 | 1 | 0 | 0 |
-1.258 | 0.2002 | 0.576 | 4083 | 1 | 1 | 1 | 0 | 0 |
-0.9676 | 0.1844 | 0.5784 | 4081 | 1 | 1 | 1 | 0 | 0 |
org2 | dimx | dimy | dimz | slice | modality | mriseries | mrimfg | mrimodel |
---|---|---|---|---|---|---|---|---|
0 | 32 | 32 | 32 | 0 | T1w | NA | NA | NA |
0 | 32 | 32 | 32 | 0 | T1w | NA | NA | NA |
0 | 32 | 32 | 32 | 0 | T1w | NA | NA | NA |
0 | 32 | 32 | 32 | 0 | T1w | NA | NA | NA |
0 | 16 | 16 | 16 | 0 | T1w | NA | NA | NA |
0 | 16 | 16 | 16 | 1 | T1w | NA | NA | NA |
0 | 16 | 16 | 16 | 2 | T1w | NA | NA | NA |
0 | 16 | 16 | 16 | 3 | T1w | NA | NA | NA |
fn
- filename
noise
- estimated noise level; just the mean
absolute error between the original image and a smoothed version of that
image
snr
- signal to noise ratio; defined from an
automatically generated background and foreground mask
fgmean / bgstd
cnr
- contrast to noise ratio; defined from an
automatically generated background and foreground mask
( fgmean - bgmean ) / bgstd
psnr
- peak signal to noise ratio between original
and smoothed image
ssim
- structural similarity between original and
smoothed image
mi
- mutual information between original and
smoothed image
reflection_error
- mean absolute error between
original and reflected image
EVR
- eigenvalue ratio - towards zero for smooth
images; toward 1 for pure noise; most reasonable medical images around
0.6 to 0.7
msk_vol
- volume of the foreground mask
spc* - image spacing
org* - image origin
dim* - image dimensions
slice - image slice index (useful for time series)
modality - inferred image modality - based on filename (could change in future)
mriseries - series description read from json if available
mrimfg - manufacturer read from json if available
mrimodel - read from json if available