def _calc_loss(self, x_iter, projs, x_initial): norm = transforms.Normalize(projs[0].mean((1,2)), projs[0].std((1,2))) percep_l = 0 proj_l = 0 tv_l = 0 ssim_l = 0 if self.w_perceptual_loss > 0.0: percep_l = self.w_perceptual_loss * self.perceptual(x_iter, x_initial.detach()) if self.w_proj_loss > 0.0: if self.randomize_projs: samples = random.sample( [i for i in range(self.N_PROJ) ], int(self.randomize_projs*self.N_PROJ) ) samples.sort() radon_ = Radon(self.IMAGE_SIZE, theta=self.theta[samples], circle=True) proj_l = self.w_proj_loss * \ self.mse(norm(radon_(x_iter)[0]), norm(projs[0,:,:,samples])) else: proj_l = self.w_proj_loss * self.mse(norm(self.radon(x_iter)[0]), norm(projs[0])) if self.w_tv_loss > 0.0: tv_l = self.w_tv_loss * tv_2d_l2(x_iter[0,0]) if self.w_ssim_loss > 0.0: ssim_l = self.w_ssim_loss * (1 - self.ssim(x_iter, x_initial.detach() )) return proj_l + percep_l + tv_l + ssim_l, (proj_l, percep_l, tv_l, ssim_l)
def __init__(self, img_size=256, delta=1, in_nc=1): super(Due_Generator, self).__init__() # self.de_recon = Inpaint_Net(in_nc, out_nc, nf, nb, gc, norm_type, act_type, mode) self.de_sino = PConvUNet(input_channels=in_nc) self.de_tomo = DenoseNet() self.angles = np.arange(0., 180., delta) self.iradon_trans = IRadon(img_size, self.angles) self.radon_trans = Radon(img_size, self.angles)
def test_radon_iradon_circle_double(self): img = torch.zeros(1,1,256,256, dtype=torch.double) img[:, :, 120:130, 120:130] = 1 circle = True theta = torch.arange(180) r = Radon(img.shape[2], theta, circle, dtype=torch.double) ir = IRadon(img.shape[2], theta, circle, dtype=torch.double) sino = r(img) reco = ir(sino) self.assertAlmostEqual(torch.nn.MSELoss()(img, reco).item(), 0, places=3)
def test_radon_iradon_not_circle_lazy_cut_output(self): img = torch.zeros(1,1,256,256) img[:, :, 120:130, 120:130] = 1 circle = False theta = torch.arange(180) r = Radon(theta=theta, circle=circle) ir = IRadon(theta=theta, circle=circle, out_size=128) sino = r(img) reco = ir(sino) self.assertAlmostEqual(torch.nn.MSELoss()(img[:,:,64:192,64:192], reco).item(), 0, places=3)
def test_ramp_filter(self): img = torch.zeros(1, 1, 256, 256) img[:, :, 120:130, 120:130] = 1 circle = True theta = torch.arange(180) r = Radon(img.shape[2], theta, circle) ir = IRadon(img.shape[2], theta, circle, use_filter=RampFilter()) reco = ir(r(img)) self.assertAlmostEqual(torch.nn.MSELoss()(img, reco).item(), 0, places=4)
def test_stackgram_istackgram_circle(self): img = torch.zeros(1, 1, 256, 256) img[:, :, 120:130, 120:130] = 1 circle = True theta = torch.arange(180) r = Radon(img.shape[2], theta, circle) ir = IRadon(img.shape[2], theta, circle) sg = Stackgram(img.shape[2], theta, circle) isg = IStackgram(img.shape[2], theta, circle) reco = ir(isg(sg(r(img)))) self.assertAlmostEqual(torch.nn.MSELoss()(img, reco).item(), 0, places=3)
def init_train(self, theta): self.theta = torch.from_numpy(theta).type(self.DTYPE) self.n_proj = len(theta) self.loss_hist = [] self.rmse_hist = [] self.ssim_hist = [] self.psnr_hist = [] self.net = self._get_net(self.net_type) self.i_iter = 0 self.r = Radon(self.IMAGE_SIZE, theta, True).to(self.DEVICE) self.masker = Masker(width = 4, mode='interpolate') self.mse = torch.nn.MSELoss().to(self.DEVICE) self.optimizer = torch.optim.Adam(self.net.parameters(), lr=self.lr) self.meta_optimizer = torch.optim.Adam(self.net.parameters(), lr=self.lr*0.1) if self.weights: self._load(self.weights)
def test_hann_butterfly_filter(self): img = torch.zeros(1, 1, 256, 256) img[:, :, 120:130, 120:130] = 1 circle = True theta = torch.arange(180) r = Radon(img.shape[2], theta, circle) ir = IRadon(img.shape[2], theta, circle, use_filter=HannButterflyFilter(img.shape[2])) reco = ir(r(img)) self.assertAlmostEqual(torch.nn.MSELoss()(img, reco).item(), 0, places=3) # Check that it's close to using HannFilter ir_og = IRadon(img.shape[2], theta, circle, use_filter=HannFilter()) reco_og = ir_og(r(img)) self.assertAlmostEqual(torch.nn.MSELoss()(reco, reco_og).item(), 0, places=4)
from skimage.data import shepp_logan_phantom from skimage.transform import radon, rescale, iradon import matplotlib.pyplot as plt import torch import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv) import pydicom import scipy.ndimage size = 512 # set size width = 512 # set size delt = 1. # smallest angle change degree = 180. # Constant Scan range from 0 to 180 degree nnradon = Radon(size, np.arange(0., degree, delt)) nniradon = IRadon(size, np.arange(0., degree, delt)) # From full degree scan to image area file = '../RadonAnalyze/dcmdata/000056.dcm' ctfile = pydicom.dcmread(file) print(ctfile) prhalf = 2 * np.arange(2 / width, width / 2, 1, dtype=np.float32) / width afhalf = 2 * np.arange(width / 2, 2 / width, -1, dtype=np.float32) / width r_l_filter = np.append(prhalf, afhalf) #设置滤波器,R-L是一种基础的滤波算法 img = ctfile.pixel_array img[img == -2000] = 0 img = img.astype('float32') # plt.figure(figsize=(8, 5))# figure 1
def calc(self, projs, theta): # recon params self.N_PROJ = len(theta) self.theta = torch.from_numpy(theta).to(self.DEVICE) self.radon = Radon(self.IMAGE_SIZE, self.theta, True).to(self.DEVICE) self.iradon = IRadon(self.IMAGE_SIZE, self.theta, True).to(self.DEVICE) # start recon if not os.path.exists(self.log_dir): os.mkdir(self.log_dir) net = self._get_net() x_initial = np_to_torch(self.noisy).type(self.DTYPE) img_gt_torch = np_to_torch(self.gt).type(self.DTYPE) net_input = torch.rand(1, self.INPUT_DEPTH, self.IMAGE_SIZE, self.IMAGE_SIZE).type(self.DTYPE) net_input_saved = net_input.detach().clone() noise = net_input.detach().clone() # Compute number of parameters s = sum([np.prod(list(p.size())) for p in net.parameters()]); print ('Number of params: %d' % s) # Optimizer optimizer = torch.optim.Adam(net.parameters(), lr=self.lr) cur_lr = self.lr projs = np_to_torch(projs).type(self.DTYPE)#self.radon(img_gt_torch).detach().clone() #np_to_torch(projs).type(self.DTYPE) # # Iterations loss_hist = [] rmse_hist = [] ssim_hist = [] ssim_noisy_hist = [] psnr_hist = [] psnr_noisy_hist = [] best_network = None best_result = None print('Reconstructing with DIP...') for i in tqdm(range(self.n_iter)): # iter optimizer.zero_grad() if self.reg_std > 0: net_input = net_input_saved + (noise.normal_() * self.reg_std) x_iter = net(net_input) loss, (proj_l, percep_l, tv_l, ssim_l) = self._calc_loss(x_iter, projs, x_initial) loss.backward() optimizer.step() # metric if i % self.SHOW_EVERY == 0: x_iter_npy = np.clip(torch_to_np(x_iter), 0, 1).astype(np.float64) rmse_hist.append( mean_squared_error(x_iter_npy, self.gt)) ssim_hist.append( structural_similarity(x_iter_npy, self.gt, multichannel=False) ) ssim_noisy_hist.append( structural_similarity(x_iter_npy, self.noisy, multichannel=False) ) psnr_hist.append( peak_signal_noise_ratio(x_iter_npy, self.gt) ) psnr_noisy_hist.append( peak_signal_noise_ratio(x_iter_npy, self.noisy) ) loss_hist.append(loss.item()) print('{}/{}- psnr: {:.3f} - psnr_noisy: {:.3f} - ssim: {:.3f} - ssim_noisy: {:.3f} - rmse: {:.5f} - loss: {:.5f} '.format( self.name, i, psnr_hist[-1], psnr_noisy_hist[-1], ssim_hist[-1], ssim_noisy_hist[-1], rmse_hist[-1], loss_hist[-1] )) #print( proj_l.item(), ssim_l.item()) # if psnr_noisy_hist[-1] / max(psnr_noisy_hist) < 0.92: # print('Falling back to previous checkpoint.') # for g in optimizer.param_groups: # g['lr'] = cur_lr / 10.0 # cur_lr = cur_lr / 10.0 # print("optimizer.lr", cur_lr) # # load network # for new_param, net_param in zip(best_network, net.parameters()): # net_param.data.copy_(new_param.cuda()) if i > 2: if loss_hist[-1] < min(loss_hist[0:-1]): # save network best_network = [x.detach().cpu() for x in net.parameters()] best_result = x_iter_npy.copy() plot_grid([x_iter_npy], self.FOCUS, save_name=self.log_dir+'/{}.png'.format(i)) self.image_r = best_result return self.image_r