From ed8a87b02df761cbaec71ecd790a647c3ef49c48 Mon Sep 17 00:00:00 2001 From: Vaggelis Papoutsellis <22398586+epapoutsellis@users.noreply.github.com> Date: Tue, 29 Oct 2019 16:18:53 +0000 Subject: fix ROF_TV (#28) * fix ROF_TV * fix ROF_TV * add TGV proximal * add new regs * added FGP_dTV * fix out * remove test to wip --- Wrappers/Python/ccpi/plugins/regularisers.py | 267 ++++++++++++++++++--- .../wip/test_LLT_ROF_framework_ccpi_regulariser.py | 179 ++++++++++++++ .../wip/test_TGV_framework_ccpi_regulariser.py | 173 +++++++++++++ .../wip/test_TVN_framework_ccpi_regulariser.py | 147 ++++++++++++ 4 files changed, 739 insertions(+), 27 deletions(-) create mode 100644 Wrappers/Python/wip/test_LLT_ROF_framework_ccpi_regulariser.py create mode 100644 Wrappers/Python/wip/test_TGV_framework_ccpi_regulariser.py create mode 100644 Wrappers/Python/wip/test_TVN_framework_ccpi_regulariser.py (limited to 'Wrappers') diff --git a/Wrappers/Python/ccpi/plugins/regularisers.py b/Wrappers/Python/ccpi/plugins/regularisers.py index 6ed9fb2..4770593 100644 --- a/Wrappers/Python/ccpi/plugins/regularisers.py +++ b/Wrappers/Python/ccpi/plugins/regularisers.py @@ -1,28 +1,28 @@ # -*- coding: utf-8 -*- -# This work is part of the Core Imaging Library developed by -# Visual Analytics and Imaging System Group of the Science Technology -# Facilities Council, STFC +# Copyright 2019 Science Technology Facilities Council +# Copyright 2019 University of Manchester +# +# This work is part of the Core Imaging Library developed by Science Technology +# Facilities Council and University of Manchester +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0.txt +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -# Copyright 2018 Jakob Jorgensen, Daniil Kazantsev and Edoardo Pasca - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This requires CCPi-Regularisation toolbox to be installed from ccpi.filters import regularisers from ccpi.filters.cpu_regularisers import TV_ENERGY from ccpi.framework import DataContainer from ccpi.optimisation.functions import Function import numpy as np +import warnings class ROF_TV(Function): @@ -32,28 +32,34 @@ class ROF_TV(Function): self.iterationsTV = iterationsTV self.time_marchstep = time_marchstep self.device = device # string for 'cpu' or 'gpu' + self.tolerance = tolerance + def __call__(self,x): # evaluate objective function of TV gradient EnergyValTV = TV_ENERGY(np.asarray(x.as_array(), dtype=np.float32), np.asarray(x.as_array(), dtype=np.float32), self.lambdaReg, 2) return 0.5*EnergyValTV[0] - def prox(self,x,tau): + + def proximal(self,x,tau, out = None): pars = {'algorithm' : ROF_TV, \ 'input' : np.asarray(x.as_array(), dtype=np.float32),\ 'regularization_parameter':self.lambdaReg*tau, \ 'number_of_iterations' :self.iterationsTV ,\ - 'time_marching_parameter':self.time_marchstep} + 'time_marching_parameter':self.time_marchstep,\ + 'tolerance':self.tolerance} res , info = regularisers.ROF_TV(pars['input'], pars['regularization_parameter'], pars['number_of_iterations'], - pars['time_marching_parameter'], self.device) + pars['time_marching_parameter'], pars['tolerance'], self.device) + + self.info = info + if out is not None: out.fill(res) else: out = x.copy() out.fill(res) return out - class FGP_TV(Function): def __init__(self,lambdaReg,iterationsTV,tolerance,methodTV,nonnegativity,printing,device): # set parameters @@ -91,7 +97,171 @@ class FGP_TV(Function): out = x.copy() out.fill(res) return out + + def convex_conjugate(self,x): + return 0.0 + + +class TGV(Function): + + def __init__(self, regularisation_parameter, alpha1, alpha2, iter_TGV, LipshitzConstant, torelance, device ): + + self.regularisation_parameter = regularisation_parameter + self.alpha1 = alpha1 + self.alpha2 = alpha2 + self.iter_TGV = iter_TGV + self.LipshitzConstant = LipshitzConstant + self.torelance = torelance + self.device = device + + def __call__(self,x): + warnings.warn("{}: the __call__ method is not currently implemented. Returning 0.".format(self.__class__.__name__)) + + # TODO this is not correct, need a TGV energy same as TV + return 0.0 + + def proximal(self, x, tau, out=None): + + pars = {'algorithm' : TGV, \ + 'input' : np.asarray(x.as_array(), dtype=np.float32),\ + 'regularisation_parameter':self.regularisation_parameter, \ + 'alpha1':self.alpha1,\ + 'alpha0':self.alpha2,\ + 'number_of_iterations' :self.iter_TGV ,\ + 'LipshitzConstant' :self.LipshitzConstant ,\ + 'tolerance_constant':self.torelance} + + res , info = regularisers.TGV(pars['input'], + pars['regularisation_parameter'], + pars['alpha1'], + pars['alpha0'], + pars['number_of_iterations'], + pars['LipshitzConstant'], + pars['tolerance_constant'],self.device) + + # info: return number of iteration and reached tolerance + # https://github.com/vais-ral/CCPi-Regularisation-Toolkit/blob/master/src/Core/regularisers_CPU/TGV_core.c#L168 + # Stopping Criteria || u^k - u^(k-1) ||_{2} / || u^{k} ||_{2} + + self.info = info + + if out is not None: + out.fill(res) + else: + out = x.copy() + out.fill(res) + return out + + def convex_conjugate(self, x): + # TODO this is not correct + return 0.0 + + +class LLT_ROF(Function): + +# pars = {'algorithm' : LLT_ROF, \ +# 'input' : noisyVol,\ +# 'regularisation_parameterROF':0.01, \ +# 'regularisation_parameterLLT':0.008, \ +# 'number_of_iterations' : 500 ,\ +# 'time_marching_parameter' :0.001 ,\ +# 'tolerance_constant':1e-06} + + def __init__(self, regularisation_parameterROF, + regularisation_parameterLLT, + iter_LLT_ROF, time_marching_parameter, torelance, device ): + + self.regularisation_parameterROF = regularisation_parameterROF + self.regularisation_parameterLLT = regularisation_parameterLLT + self.iter_LLT_ROF = iter_LLT_ROF + self.time_marching_parameter = time_marching_parameter + self.torelance = torelance + self.device = device + + def __call__(self,x): + warnings.warn("{}: the __call__ method is not currently implemented. Returning 0.".format(self.__class__.__name__)) + + # TODO this is not correct, need a TGV energy same as TV + return 0.0 + + def proximal(self, x, tau, out=None): + + pars = {'algorithm' : LLT_ROF, \ + 'input' : np.asarray(x.as_array(), dtype=np.float32),\ + 'regularisation_parameterROF':self.regularisation_parameterROF, \ + 'regularisation_parameterLLT':self.regularisation_parameterLLT, + 'number_of_iterations' :self.iter_LLT_ROF ,\ + 'time_marching_parameter': self.time_marching_parameter,\ + 'tolerance_constant':self.torelance} + + + + res , info = regularisers.LLT_ROF(pars['input'], + pars['regularisation_parameterROF'], + pars['regularisation_parameterLLT'], + pars['number_of_iterations'], + pars['time_marching_parameter'], + pars['tolerance_constant'],self.device) + + # info: return number of iteration and reached tolerance + # https://github.com/vais-ral/CCPi-Regularisation-Toolkit/blob/master/src/Core/regularisers_CPU/TGV_core.c#L168 + # Stopping Criteria || u^k - u^(k-1) ||_{2} / || u^{k} ||_{2} + + self.info = info + + +class FGP_dTV(Function): + def __init__(self, refdata, regularisation_parameter, iterations, + tolerance, eta_const, methodTV, nonneg, device='cpu'): + # set parameters + self.lambdaReg = regularisation_parameter + self.iterationsTV = iterations + self.tolerance = tolerance + self.methodTV = methodTV + self.nonnegativity = nonneg + self.device = device # string for 'cpu' or 'gpu' + self.refData = np.asarray(refdata.as_array(), dtype=np.float32) + self.eta = eta_const + + def __call__(self,x): + # evaluate objective function of TV gradient + EnergyValTV = TV_ENERGY(np.asarray(x.as_array(), dtype=np.float32), np.asarray(x.as_array(), dtype=np.float32), self.lambdaReg, 2) + return 0.5*EnergyValTV[0] + def proximal(self,x,tau, out=None): + pars = {'algorithm' : FGP_dTV, \ + 'input' : np.asarray(x.as_array(), dtype=np.float32),\ + 'regularization_parameter':self.lambdaReg*tau, \ + 'number_of_iterations' :self.iterationsTV ,\ + 'tolerance_constant':self.tolerance,\ + 'methodTV': self.methodTV ,\ + 'nonneg': self.nonnegativity ,\ + 'eta_const' : self.eta,\ + 'refdata':self.refData} + #inputData, refdata, regularisation_parameter, iterations, + # tolerance_param, eta_const, methodTV, nonneg, device='cpu' + res , info = regularisers.FGP_dTV(pars['input'], + pars['refdata'], + pars['regularization_parameter'], + pars['number_of_iterations'], + pars['tolerance_constant'], + pars['eta_const'], + pars['methodTV'], + pars['nonneg'], + self.device) + if out is not None: + out.fill(res) + else: + out = x.copy() + out.fill(res) + return out + + def convex_conjugate(self, x): + # TODO this is not correct + return 0.0 + + + class SB_TV(Function): def __init__(self,lambdaReg,iterationsTV,tolerance,methodTV,printing,device): # set parameters @@ -101,28 +271,71 @@ class SB_TV(Function): self.methodTV = methodTV self.printing = printing self.device = device # string for 'cpu' or 'gpu' + def __call__(self,x): + # evaluate objective function of TV gradient EnergyValTV = TV_ENERGY(np.asarray(x.as_array(), dtype=np.float32), np.asarray(x.as_array(), dtype=np.float32), self.lambdaReg, 2) return 0.5*EnergyValTV[0] + def proximal(self,x,tau, out=None): pars = {'algorithm' : SB_TV, \ 'input' : np.asarray(x.as_array(), dtype=np.float32),\ 'regularization_parameter':self.lambdaReg*tau, \ 'number_of_iterations' :self.iterationsTV ,\ 'tolerance_constant':self.tolerance,\ - 'methodTV': self.methodTV ,\ - 'printingOut': self.printing} + 'methodTV': self.methodTV} res , info = regularisers.SB_TV(pars['input'], pars['regularization_parameter'], pars['number_of_iterations'], pars['tolerance_constant'], - pars['methodTV'], - pars['printingOut'], self.device) + pars['methodTV'], self.device) + + self.info = info + if out is not None: out.fill(res) else: out = x.copy() out.fill(res) - return out + return out + + + +class TNV(Function): + + def __init__(self,regularisation_parameter,iterationsTNV,tolerance): + + # set parameters + self.regularisation_parameter = regularisation_parameter + self.iterationsTNV = iterationsTNV + self.tolerance = tolerance + + + def __call__(self,x): + warnings.warn("{}: the __call__ method is not currently implemented. Returning 0.".format(self.__class__.__name__)) + # evaluate objective function of TV gradient + return 0.0 + + def proximal(self,x,tau, out=None): + pars = {'algorithm' : TNV, \ + 'input' : np.asarray(x.as_array(), dtype=np.float32),\ + 'regularisation_parameter':self.regularisation_parameter, \ + 'number_of_iterations' :self.iterationsTNV,\ + 'tolerance_constant':self.tolerance} + + res = regularisers.TNV(pars['input'], + pars['regularisation_parameter'], + pars['number_of_iterations'], + pars['tolerance_constant']) + + #self.info = info + + if out is not None: + out.fill(res) + else: + out = x.copy() + out.fill(res) + return out + diff --git a/Wrappers/Python/wip/test_LLT_ROF_framework_ccpi_regulariser.py b/Wrappers/Python/wip/test_LLT_ROF_framework_ccpi_regulariser.py new file mode 100644 index 0000000..3368732 --- /dev/null +++ b/Wrappers/Python/wip/test_LLT_ROF_framework_ccpi_regulariser.py @@ -0,0 +1,179 @@ +from ccpi.framework import ImageData, TestData + +import numpy as np +import numpy +import matplotlib.pyplot as plt + +from ccpi.optimisation.algorithms import PDHG + +from ccpi.optimisation.operators import BlockOperator, Identity, \ + Gradient, SymmetrizedGradient, ZeroOperator +from ccpi.optimisation.functions import ZeroFunction, L1Norm, \ + MixedL21Norm, BlockFunction, KullbackLeibler, L2NormSquared +import os +import sys +from ccpi.plugins.regularisers import TGV, LLT_ROF + +# user supplied input +if len(sys.argv) > 1: + which_noise = int(sys.argv[1]) +else: + which_noise = 0 +print ("Applying {} noise") + +if len(sys.argv) > 2: + method = sys.argv[2] +else: + method = '0' +print ("method ", method) + + +loader = TestData(data_dir=os.path.join(sys.prefix, 'share','ccpi')) +data = loader.load(TestData.SHAPES) +ig = data.geometry +ag = ig + +# Create noisy data. +noises = ['gaussian', 'poisson', 's&p'] +noise = noises[which_noise] +if noise == 's&p': + n1 = TestData.random_noise(data.as_array(), mode = noise, salt_vs_pepper = 0.9, amount=0.2, seed=10) +elif noise == 'poisson': + scale = 5 + n1 = TestData.random_noise(data.as_array()/scale, mode = noise, seed = 10)*scale +elif noise == 'gaussian': + n1 = TestData.random_noise(data.as_array(), mode = noise, seed = 10) +else: + raise ValueError('Unsupported Noise ', noise) +noisy_data = ImageData(n1) + +# Show Ground Truth and Noisy Data +plt.figure(figsize=(10,5)) +plt.subplot(1,2,1) +plt.imshow(data.as_array()) +plt.title('Ground Truth') +plt.colorbar() +plt.subplot(1,2,2) +plt.imshow(noisy_data.as_array()) +plt.title('Noisy Data') +plt.colorbar() +plt.show() + +# Regularisation Parameter depending on the noise distribution +if noise == 's&p': + alpha = 0.8 +elif noise == 'poisson': + alpha = .3 +elif noise == 'gaussian': + alpha = .2 + +beta = 2 * alpha + +# Fidelity +if noise == 's&p': + f3 = L1Norm(b=noisy_data) +elif noise == 'poisson': + f3 = KullbackLeibler(noisy_data) +elif noise == 'gaussian': + f3 = 0.5 * L2NormSquared(b=noisy_data) + +if method == '0': + + # Create operators + op11 = Gradient(ig) + op12 = Identity(op11.range_geometry()) + + op22 = SymmetrizedGradient(op11.domain_geometry()) + op21 = ZeroOperator(ig, op22.range_geometry()) + + op31 = Identity(ig, ag) + op32 = ZeroOperator(op22.domain_geometry(), ag) + + operator = BlockOperator(op11, -1*op12, op21, op22, op31, op32, shape=(3,2) ) + + f1 = alpha * MixedL21Norm() + f2 = beta * MixedL21Norm() + + f = BlockFunction(f1, f2, f3) + g = ZeroFunction() + +else: + + # Create operators + op11 = Gradient(ig) + op12 = Identity(op11.range_geometry()) + op22 = SymmetrizedGradient(op11.domain_geometry()) + op21 = ZeroOperator(ig, op22.range_geometry()) + + operator = BlockOperator(op11, -1*op12, op21, op22, shape=(2,2) ) + + f1 = alpha * MixedL21Norm() + f2 = beta * MixedL21Norm() + + f = BlockFunction(f1, f2) + g = BlockFunction(f3, ZeroFunction()) + +# Compute operator Norm +normK = operator.norm() + +# Primal & dual stepsizes +#sigma = 1/normK +#tau = 1/normK + +sigma = 1 +tau = 1/(sigma*normK**2) + +# Setup and run the PDHG algorithm +pdhg = PDHG(f=f,g=g,operator=operator, tau=tau, sigma=sigma) +pdhg.max_iteration = 5000 +pdhg.update_objective_interval = 500 +pdhg.run(5000) + +# Show results +plt.figure(figsize=(20,5)) +plt.subplot(1,4,1) +plt.imshow(data.as_array()) +plt.title('Ground Truth') +plt.colorbar() +plt.subplot(1,4,2) +plt.imshow(noisy_data.as_array()) +plt.title('Noisy Data') +plt.colorbar() +plt.subplot(1,4,3) +plt.imshow(pdhg.get_output()[0].as_array()) +plt.title('TGV Reconstruction') +plt.colorbar() +plt.subplot(1,4,4) +plt.plot(np.linspace(0,ig.shape[1],ig.shape[1]), data.as_array()[int(ig.shape[0]/2),:], label = 'GTruth') +plt.plot(np.linspace(0,ig.shape[1],ig.shape[1]), pdhg.get_output()[0].as_array()[int(ig.shape[0]/2),:], label = 'TGV reconstruction') +plt.legend() +plt.title('Middle Line Profiles') +plt.show() + +#%% Run CCPi-regulariser +# The TGV implementation is using PDHG algorithm with fixed +# sigma = tau = 1/sqrt(12) + +# There is an early stopping criteria +# https://github.com/vais-ral/CCPi-Regularisation-Toolkit/blob/master/src/Core/regularisers_CPU/TGV_core.c#L168 + +g = TGV(1, alpha, beta, 2000, normK**2, 1e-6, 'gpu') +#alphaROF = 0.1 +#alphaLLT = 0.05 +#g = LLT_ROF(alphaROF, alphaLLT, 500, 0.001, 1e-6, 'gpu') +sol = g.proximal(noisy_data, 1) + +plt.imshow(sol.as_array()) +plt.show() + +plt.imshow(pdhg.get_output()[0].as_array()) +plt.show() + +plt.imshow(np.abs(sol.as_array() - pdhg.get_output()[0].as_array())) +plt.colorbar() +plt.show() + +#%% + +plt.plot(np.linspace(0,299,300),sol.as_array()[100,:], np.linspace(0,299,300),pdhg.get_output()[0].as_array()[100,:]) + diff --git a/Wrappers/Python/wip/test_TGV_framework_ccpi_regulariser.py b/Wrappers/Python/wip/test_TGV_framework_ccpi_regulariser.py new file mode 100644 index 0000000..a6f6094 --- /dev/null +++ b/Wrappers/Python/wip/test_TGV_framework_ccpi_regulariser.py @@ -0,0 +1,173 @@ +from ccpi.framework import ImageData, TestData + +import numpy as np +import numpy +import matplotlib.pyplot as plt + +from ccpi.optimisation.algorithms import PDHG + +from ccpi.optimisation.operators import BlockOperator, Identity, \ + Gradient, SymmetrizedGradient, ZeroOperator +from ccpi.optimisation.functions import ZeroFunction, L1Norm, \ + MixedL21Norm, BlockFunction, KullbackLeibler, L2NormSquared +import os +import sys +from ccpi.plugins.regularisers import TGV + +# user supplied input +if len(sys.argv) > 1: + which_noise = int(sys.argv[1]) +else: + which_noise = 0 +print ("Applying {} noise") + +if len(sys.argv) > 2: + method = sys.argv[2] +else: + method = '1' +print ("method ", method) + + +loader = TestData(data_dir=os.path.join(sys.prefix, 'share','ccpi')) +data = loader.load(TestData.SHAPES) +ig = data.geometry +ag = ig + +# Create noisy data. +noises = ['gaussian', 'poisson', 's&p'] +noise = noises[which_noise] +if noise == 's&p': + n1 = TestData.random_noise(data.as_array(), mode = noise, salt_vs_pepper = 0.9, amount=0.2, seed=10) +elif noise == 'poisson': + scale = 5 + n1 = TestData.random_noise(data.as_array()/scale, mode = noise, seed = 10)*scale +elif noise == 'gaussian': + n1 = TestData.random_noise(data.as_array(), mode = noise, seed = 10) +else: + raise ValueError('Unsupported Noise ', noise) +noisy_data = ImageData(n1) + +# Show Ground Truth and Noisy Data +plt.figure(figsize=(10,5)) +plt.subplot(1,2,1) +plt.imshow(data.as_array()) +plt.title('Ground Truth') +plt.colorbar() +plt.subplot(1,2,2) +plt.imshow(noisy_data.as_array()) +plt.title('Noisy Data') +plt.colorbar() +plt.show() + +# Regularisation Parameter depending on the noise distribution +if noise == 's&p': + alpha = 0.8 +elif noise == 'poisson': + alpha = .3 +elif noise == 'gaussian': + alpha = .2 + +beta = 2 * alpha + +# Fidelity +if noise == 's&p': + f3 = L1Norm(b=noisy_data) +elif noise == 'poisson': + f3 = KullbackLeibler(noisy_data) +elif noise == 'gaussian': + f3 = 0.5 * L2NormSquared(b=noisy_data) + +if method == '0': + + # Create operators + op11 = Gradient(ig) + op12 = Identity(op11.range_geometry()) + + op22 = SymmetrizedGradient(op11.domain_geometry()) + op21 = ZeroOperator(ig, op22.range_geometry()) + + op31 = Identity(ig, ag) + op32 = ZeroOperator(op22.domain_geometry(), ag) + + operator = BlockOperator(op11, -1*op12, op21, op22, op31, op32, shape=(3,2) ) + + f1 = alpha * MixedL21Norm() + f2 = beta * MixedL21Norm() + + f = BlockFunction(f1, f2, f3) + g = ZeroFunction() + +else: + + # Create operators + op11 = Gradient(ig) + op12 = Identity(op11.range_geometry()) + op22 = SymmetrizedGradient(op11.domain_geometry()) + op21 = ZeroOperator(ig, op22.range_geometry()) + + operator = BlockOperator(op11, -1*op12, op21, op22, shape=(2,2) ) + + f1 = alpha * MixedL21Norm() + f2 = beta * MixedL21Norm() + + f = BlockFunction(f1, f2) + g = BlockFunction(f3, ZeroFunction()) + +# Compute operator Norm +normK = operator.norm() + +# Primal & dual stepsizes +sigma = 1/normK +tau = 1/normK + +# Setup and run the PDHG algorithm +pdhg = PDHG(f=f,g=g,operator=operator, tau=tau, sigma=sigma) +pdhg.max_iteration = 5000 +pdhg.update_objective_interval = 500 +pdhg.run(5000) + +# Show results +plt.figure(figsize=(20,5)) +plt.subplot(1,4,1) +plt.imshow(data.subset(channel=0).as_array()) +plt.title('Ground Truth') +plt.colorbar() +plt.subplot(1,4,2) +plt.imshow(noisy_data.subset(channel=0).as_array()) +plt.title('Noisy Data') +plt.colorbar() +plt.subplot(1,4,3) +plt.imshow(pdhg.get_output()[0].as_array()) +plt.title('TGV Reconstruction') +plt.colorbar() +plt.subplot(1,4,4) +plt.plot(np.linspace(0,ig.shape[1],ig.shape[1]), data.as_array()[int(ig.shape[0]/2),:], label = 'GTruth') +plt.plot(np.linspace(0,ig.shape[1],ig.shape[1]), pdhg.get_output()[0].as_array()[int(ig.shape[0]/2),:], label = 'TGV reconstruction') +plt.legend() +plt.title('Middle Line Profiles') +plt.show() + +# Run CCPi-regulariser +# The TGV implementation is using PDHG algorithm with fixed +# sigma = tau = 1/sqrt(12) + +# There is an early stopping criteria +# https://github.com/vais-ral/CCPi-Regularisation-Toolkit/blob/master/src/Core/regularisers_CPU/TGV_core.c#L168 + +g = TGV(1, alpha, beta, 5000, 12, 1e-6, 'gpu') +sol = g.proximal(noisy_data, 1) + +plt.imshow(sol.as_array()) +plt.show() + +plt.imshow(pdhg.get_output()[0].as_array()) +plt.show() + +plt.imshow(np.abs(sol.as_array() - pdhg.get_output()[0].as_array())) +plt.colorbar() +plt.show() + +#%% + +plt.plot(np.linspace(0,299,300),sol.as_array()[100,:], np.linspace(0,299,300),pdhg.get_output()[0].as_array()[100,:]) + diff --git a/Wrappers/Python/wip/test_TVN_framework_ccpi_regulariser.py b/Wrappers/Python/wip/test_TVN_framework_ccpi_regulariser.py new file mode 100644 index 0000000..a0c893d --- /dev/null +++ b/Wrappers/Python/wip/test_TVN_framework_ccpi_regulariser.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Thu Feb 22 11:39:43 2018 + +Demonstration of CPU regularisers + +@authors: Daniil Kazantsev, Edoardo Pasca +""" + +import matplotlib.pyplot as plt +import numpy as np +import os +import timeit +from ccpi.filters.regularisers import ROF_TV, FGP_TV, SB_TV, TGV, LLT_ROF, FGP_dTV, TNV, NDF, Diff4th +from ccpi.filters.regularisers import PatchSelect, NLTV +from ccpi.supp.qualitymetrics import QualityTools + +from ccpi.plugins.regularisers import TNV as TNV_new +############################################################################### +def printParametersToString(pars): + txt = r'' + for key, value in pars.items(): + if key== 'algorithm' : + txt += "{0} = {1}".format(key, value.__name__) + elif key == 'input': + txt += "{0} = {1}".format(key, np.shape(value)) + elif key == 'refdata': + txt += "{0} = {1}".format(key, np.shape(value)) + else: + txt += "{0} = {1}".format(key, value) + txt += '\n' + return txt +############################################################################### + +filename = 'lena_gray_512.tif' + +# read image +Im = plt.imread(filename) +Im = np.asarray(Im, dtype='float32') + +Im = Im/255.0 +perc = 0.05 +u0 = Im + np.random.normal(loc = 0 , + scale = perc * Im , + size = np.shape(Im)) +u_ref = Im + np.random.normal(loc = 0 , + scale = 0.01 * Im , + size = np.shape(Im)) +(N,M) = np.shape(u0) +# map the u0 u0->u0>0 +# f = np.frompyfunc(lambda x: 0 if x < 0 else x, 1,1) +u0 = u0.astype('float32') +u_ref = u_ref.astype('float32') + +# change dims to check that modules work with non-squared images +""" +M = M-100 +u_ref2 = np.zeros([N,M],dtype='float32') +u_ref2[:,0:M] = u_ref[:,0:M] +u_ref = u_ref2 +del u_ref2 + +u02 = np.zeros([N,M],dtype='float32') +u02[:,0:M] = u0[:,0:M] +u0 = u02 +del u02 + +Im2 = np.zeros([N,M],dtype='float32') +Im2[:,0:M] = Im[:,0:M] +Im = Im2 +del Im2 +""" + +#%% +print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") +print ("__________Total nuclear Variation__________") +print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") + +## plot +fig = plt.figure() +plt.suptitle('Performance of TNV regulariser using the CPU') +a=fig.add_subplot(1,2,1) +a.set_title('Noisy Image') +imgplot = plt.imshow(u0,cmap="gray") + +channelsNo = 5 +noisyVol = np.zeros((channelsNo,N,M),dtype='float32') +idealVol = np.zeros((channelsNo,N,M),dtype='float32') + +for i in range (channelsNo): + noisyVol[i,:,:] = Im + np.random.normal(loc = 0 , scale = perc * Im , size = np.shape(Im)) + idealVol[i,:,:] = Im + +# set parameters +pars = {'algorithm' : TNV, \ + 'input' : noisyVol,\ + 'regularisation_parameter': 0.04, \ + 'number_of_iterations' : 200 ,\ + 'tolerance_constant':1e-05 + } + +print ("#############TNV CPU#################") +start_time = timeit.default_timer() +tnv_cpu = TNV(pars['input'], + pars['regularisation_parameter'], + pars['number_of_iterations'], + pars['tolerance_constant']) + +Qtools = QualityTools(idealVol, tnv_cpu) +pars['rmse'] = Qtools.rmse() + +txtstr = printParametersToString(pars) +txtstr += "%s = %.3fs" % ('elapsed time',timeit.default_timer() - start_time) +print (txtstr) +a=fig.add_subplot(1,2,2) + +# these are matplotlib.patch.Patch properties +props = dict(boxstyle='round', facecolor='wheat', alpha=0.75) +# place a text box in upper left in axes coords +a.text(0.15, 0.25, txtstr, transform=a.transAxes, fontsize=14, + verticalalignment='top', bbox=props) +imgplot = plt.imshow(tnv_cpu[3,:,:], cmap="gray") +plt.title('{}'.format('CPU results')) + +#%% +from ccpi.framework import ImageData +g = TNV_new(0.04, 200, 1e-5) +sol = g.proximal(ImageData(noisyVol), 1) + +#%% +plt.figure(figsize=(10,10)) +plt.subplot(3,1,1) +plt.imshow(sol.as_array()[2]) +plt.colorbar() + +plt.subplot(3,1,2) +plt.imshow(tnv_cpu[2]) +plt.colorbar() + +plt.subplot(3,1,3) +plt.imshow(np.abs(tnv_cpu[2] - sol.as_array()[2])) +plt.colorbar() + +plt.show() + +#plt.imshow(sol.as_array()) \ No newline at end of file -- cgit v1.2.3