SAKE Reconstruction Demo
This a demo on how to use the SAKE method to perform autocalibration with no autocalibration lines. It is based on P. Shin et. al, "Calibrationless Parallel Imaging Reconstruction Based on Structured Low-Rank Matrix Completion" 2013, Accepted to MRM. The demo here shows how to recover a calibration area and then use ESPIRiT to recover the image.
Contents
Prepare DATA
load brain_8ch DATA = DATA/max(max(max(abs(ifft2c(DATA))))) + eps; ncalib = 48; ksize = [6,6]; % ESPIRiT kernel-window-size sakeIter = 100; wnthresh = 1.8; % Window-normalized number of singular values to threshold eigThresh_im = 0.9; % threshold of eigenvectors in image space [sx,sy,Nc] = size(DATA); mask = mask_nocalib_x2half; % choose a 3x no calibration mask DATAc = DATA.* repmat(mask,[1,1,size(DATA,3)]); calibc = crop(DATAc,[ncalib,ncalib,8]);
Display sampling mask and root sos of zero-filled reconstruction
im = ifft2c(DATAc);
figure, imshow(cat(2,mask,sos(im)),[]);
title('Left: Sampling mask, Right: root sos of zero-filled reconstruction');
colormap((gray(256))); colorbar;
Singular values of the calibration matrix before SAKE
compute Calibration matrix, perform SVD and convert singular vectors into k-space kernels
[k,S] = dat2Kernel(calibc,ksize);
Display the singular vectors and values of the calibration matrix. There is no distinct null space anymore -- due to the undersampling
kdisp = reshape(k,[ksize(1)*ksize(2)*Nc,ksize(1)*ksize(2)*Nc]); figure, subplot(211), plot([1:ksize(1)*ksize(2)*Nc],S,'LineWidth',2); hold on, plot([wnthresh,wnthresh]*prod(ksize),[0,S(1)],'g--','LineWidth',2) legend('signular vector value','threshold') title('Singular Vectors Before SAKE') subplot(212), imagesc(abs(kdisp)), colormap(gray(256)); xlabel('Singular value #'); title('Singular vectors')
Compute ESPIRiT maps to show that the maps are corrupted as well.
[M,W] = kernelEig(k(:,:,:,1:floor(wnthresh*prod(ksize))),[sx,sy]);
show eigen-values and eigen-vectors. These are corrupted due to the undersampling
figure, imshow3(abs(W),[],[1,Nc]); title('Eigen Values in Image space'); colormap((gray(256))); colorbar; figure, imshow3(abs(M),[],[Nc,Nc]); title('Magnitude of Eigen Vectors'); colormap(gray(256)); colorbar;
Warning: Image is too big to fit on screen; displaying at 67%
Perform SAKE reconstruction to recover the calibration area
disp('Performing SAKE recovery of calibration'); tic;, calib = SAKE(calibc, [ksize], wnthresh,sakeIter, 0);toc disp('Done')
Performing SAKE recovery of calibration Elapsed time is 30.774142 seconds. Done
Singular values of the calibration matrix and ESPIRiT Maps after SAKE
Sake now shows a null space and improved Maps.
[k,S] = dat2Kernel(calib,ksize); [M,W] = kernelEig(k(:,:,:,1:floor(wnthresh*prod(ksize))),[sx,sy]); kdisp = reshape(k,[ksize(1)*ksize(2)*Nc,ksize(1)*ksize(2)*Nc]); figure, subplot(211), plot([1:ksize(1)*ksize(2)*Nc],S,'LineWidth',2); hold on, plot([wnthresh,wnthresh]*prod(ksize),[0,S(1)],'g--','LineWidth',2) legend('signular vector value','threshold') title('Singular Vectors after SAKE') subplot(212), imagesc(abs(kdisp)), colormap(gray(256)); xlabel('Singular value #'); title('Singular vectors') figure, imshow3(abs(W),[],[1,Nc]); title('Eigen Values in Image space After SAKE'); colormap((gray(256))); colorbar; figure, imshow3(abs(M),[],[Nc,Nc]); title('Magnitude of Eigen Vectors After SAKE'); colormap(gray(256)); colorbar;
Warning: Image is too big to fit on screen; displaying at 67%
Compute Soft-SENSE ESPIRiT Maps
crop sensitivity maps according to eigenvalues==1. Note that we have to use 2 sets of maps. Here we weight the 2 maps with the eigen-values
maps = M(:,:,:,end-1:end); % Weight the eigenvectors with soft-senses eigen-values weights = W(:,:,end-1:end) ; weights = (weights - eigThresh_im)./(1-eigThresh_im).* (W(:,:,end-1:end) > eigThresh_im); weights = -cos(pi*weights)/2 + 1/2; % create and ESPIRiT operator ESP = ESPIRiT(maps,weights); nIterCG = 15;
Reconsturctions
ESPIRiT CG reconstruction with soft-sense and 2 sets of maps
disp('Performing ESPIRiT reconstruction from 2 maps') tic; [reskESPIRiT, resESPIRiT] = cgESPIRiT(DATAc,ESP, nIterCG, 0.01,DATAc*0); toc figure, imshow(cat(2,sos(ifft2c(DATA-reskESPIRiT))*10,sos(resESPIRiT.*weights)),[0,1]) title('Left: Reconstruction error x10, Right: SAKE+ESPIRiT reconstruction')
Performing ESPIRiT reconstruction from 2 maps Elapsed time is 3.451226 seconds.