Compressed Sensing
We next consider a compressed sensing reconstruction using one slice of a knee dataset obtained from mridata.org. The example can be run by entering
include(joinpath(dirname(pathof(MRIReco)),"../docs/src/examples/exampleCS.jl"))
into the Julia REPL.
We first perform a baseline reconstruction with fully sampled data:
# load fully sampled data
f = ISMRMRDFile("data/knee_3dFSE_slice170.h5")
acqData = AcquisitionData(f);
# reconstruct
params = Dict{Symbol, Any}()
params[:reco] = "direct"
params[:reconSize] = (320,320) # this size is also contained in acqData.encodingSize
img = reconstruction(acqData, params)
img = sqrt.(sum(img.^2,dims=5))
The result looks like this:
To simulate an undersampled reconstruction, we retrospectively undersample the data using a Poisson disk pattern.
redFac = 4.0
acqDataSub = sample_kspace(acqData,redFac,"poisson",calsize=30,profiles=false);
The sampling pattern looks like this:
Then, we estimate the coil sensitivities using ESPIRiT
smaps = espirit(acqData,(6,6),30,eigThresh_1=0.035,eigThresh_2=0.98)
and perform a simple SENSE reconstruction. We expect a degradation in image quality due to the subsampling:
params = Dict{Symbol, Any}()
params[:reco] = "multiCoil"
params[:reconSize] = (320,320)
params[:senseMaps] = smaps
params[:solver] = CGNR
params[:reg] = L2Regularization(1.e-4)
params[:iterations] = 5
params[:normalizeReg] = MeasurementBasedNormalization()
img_cg = reconstruction(acqDataSub, params)
Using TV regularization recquires us to change some parameters:
params = Dict{Symbol, Any}()
params[:reco] = "multiCoil"
params[:reconSize] = (320,320)
params[:senseMaps] = smaps
params[:solver] = ADMM
params[:reg] = TVRegularization(1.e-1, shape = (320, 320))
params[:iterations] = 50
params[:ρ] = 0.1
params[:absTol] = 1.e-4
params[:relTol] = 1.e-2
params[:tolInner] = 1.e-2
params[:normalizeReg] = MeasurementBasedNormalization()
img_tv = reconstruction(acqDataSub, params)
Lets compare the results, left the regular SENSE reconstruction and right the TV reglarized solution: