diff options
author | Willem Jan Palenstijn <wjp@usecode.org> | 2016-11-18 08:57:46 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-18 08:57:46 -0800 |
commit | 6c9756b1d26d1e920b12cdcf8580362690427ddc (patch) | |
tree | 5e4bee74486176215ede3fc28e39420dfca861e1 | |
parent | 1a092b53bddd7e31a3fcf12a13aabd404e91d215 (diff) | |
parent | 78985a7b623ca8596e2acd57d4bf0ab052900e3a (diff) | |
download | astra-6c9756b1d26d1e920b12cdcf8580362690427ddc.tar.gz astra-6c9756b1d26d1e920b12cdcf8580362690427ddc.tar.bz2 astra-6c9756b1d26d1e920b12cdcf8580362690427ddc.tar.xz astra-6c9756b1d26d1e920b12cdcf8580362690427ddc.zip |
Merge pull request #66 from wjp/iter_plugins
Add SIRT, CGLS python plugins
-rw-r--r-- | build/linux/Makefile.in | 2 | ||||
-rw-r--r-- | python/astra/__init__.py | 1 | ||||
-rw-r--r-- | python/astra/plugins/__init__.py | 29 | ||||
-rw-r--r-- | python/astra/plugins/cgls.py | 99 | ||||
-rw-r--r-- | python/astra/plugins/sirt.py | 90 | ||||
-rw-r--r-- | python/builder.py | 2 | ||||
-rw-r--r-- | samples/python/s018_plugin.py | 12 |
7 files changed, 234 insertions, 1 deletions
diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in index f10f482..14027e1 100644 --- a/build/linux/Makefile.in +++ b/build/linux/Makefile.in @@ -399,8 +399,10 @@ ifeq ($(python),yes) install-python: py $(INSTALL_SH) -m 755 -d @prefix@/python $(INSTALL_SH) -m 755 -d @prefix@/python/astra + $(INSTALL_SH) -m 755 -d @prefix@/python/astra/plugins $(INSTALL_SH) -m 644 python/finalbuild/astra/*.so @prefix@/python/astra $(INSTALL_SH) -m 644 python/finalbuild/astra/*.py @prefix@/python/astra + $(INSTALL_SH) -m 644 python/finalbuild/astra/plugins/*.py @prefix@/python/astra/plugins $(INSTALL_SH) -m 644 python/finalbuild/*.egg-info @prefix@/python/ @echo "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" @echo "To use ASTRA in Python, add @prefix@/python/ to your PYTHONPATH" diff --git a/python/astra/__init__.py b/python/astra/__init__.py index 515d9a2..f4f5fe8 100644 --- a/python/astra/__init__.py +++ b/python/astra/__init__.py @@ -35,6 +35,7 @@ from . import projector from . import projector3d from . import matrix from . import plugin +from . import plugins from . import log from .optomo import OpTomo diff --git a/python/astra/plugins/__init__.py b/python/astra/plugins/__init__.py new file mode 100644 index 0000000..71e9b64 --- /dev/null +++ b/python/astra/plugins/__init__.py @@ -0,0 +1,29 @@ +# ----------------------------------------------------------------------- +# Copyright: 2010-2016, iMinds-Vision Lab, University of Antwerp +# 2013-2016, CWI, Amsterdam +# +# Contact: astra@uantwerpen.be +# Website: http://sf.net/projects/astra-toolbox +# +# This file is part of the ASTRA Toolbox. +# +# +# The ASTRA Toolbox is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# The ASTRA Toolbox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. +# +# ----------------------------------------------------------------------- + + +from .sirt import SIRTPlugin +from .cgls import CGLSPlugin + diff --git a/python/astra/plugins/cgls.py b/python/astra/plugins/cgls.py new file mode 100644 index 0000000..2f4970b --- /dev/null +++ b/python/astra/plugins/cgls.py @@ -0,0 +1,99 @@ +# ----------------------------------------------------------------------- +# Copyright: 2010-2016, iMinds-Vision Lab, University of Antwerp +# 2013-2016, CWI, Amsterdam +# +# Contact: astra@uantwerpen.be +# Website: http://sf.net/projects/astra-toolbox +# +# This file is part of the ASTRA Toolbox. +# +# +# The ASTRA Toolbox is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# The ASTRA Toolbox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. +# +# ----------------------------------------------------------------------- + + +import astra +import numpy as np +import six + +class CGLSPlugin(astra.plugin.base): + """CGLS.""" + + astra_name = "CGLS-PLUGIN" + + def initialize(self,cfg): + self.W = astra.OpTomo(cfg['ProjectorId']) + self.vid = cfg['ReconstructionDataId'] + self.sid = cfg['ProjectionDataId'] + + try: + v = astra.data2d.get_shared(self.vid) + s = astra.data2d.get_shared(self.sid) + self.data_mod = astra.data2d + except Exception: + v = astra.data3d.get_shared(self.vid) + s = astra.data3d.get_shared(self.sid) + self.data_mod = astra.data3d + + def run(self, its): + v = self.data_mod.get_shared(self.vid) + s = self.data_mod.get_shared(self.sid) + z = np.zeros(v.shape, dtype=np.float32) + p = np.zeros(v.shape, dtype=np.float32) + r = np.zeros(s.shape, dtype=np.float32) + w = np.zeros(s.shape, dtype=np.float32) + W = self.W + + # r = s - W*v + W.FP(v, out=w) + r[:] = s + r -= w + + # p = W'*r + W.BP(r, out=p) + + # gamma = <p,p> + gamma = np.dot(p.ravel(), p.ravel()) + + for i in range(its): + # w = W * p + W.FP(p, out=w) + + # alpha = gamma / <w,w> + alpha = gamma / np.dot(w.ravel(), w.ravel()) + + # v += alpha * p + z[:] = p + z *= alpha + v += z + + # r -= alpha * w + w *= -alpha; + r += w + + # z = W' * r + W.BP(r, out=z) + + # beta = <z,z> / gamma + newgamma = np.dot(z.ravel(), z.ravel()) + beta = newgamma / gamma + + # gamma = <z,z> + gamma = newgamma + + # p = z + beta * p + p *= beta + p += z + diff --git a/python/astra/plugins/sirt.py b/python/astra/plugins/sirt.py new file mode 100644 index 0000000..a0f1230 --- /dev/null +++ b/python/astra/plugins/sirt.py @@ -0,0 +1,90 @@ +# ----------------------------------------------------------------------- +# Copyright: 2010-2016, iMinds-Vision Lab, University of Antwerp +# 2013-2016, CWI, Amsterdam +# +# Contact: astra@uantwerpen.be +# Website: http://sf.net/projects/astra-toolbox +# +# This file is part of the ASTRA Toolbox. +# +# +# The ASTRA Toolbox is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# The ASTRA Toolbox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. +# +# ----------------------------------------------------------------------- + + +import astra +import numpy as np +import six + +class SIRTPlugin(astra.plugin.base): + """SIRT. + + Options: + + 'Relaxation': relaxation factor (optional) + 'MinConstraint': constrain values to at least this (optional) + 'MaxConstraint': constrain values to at most this (optional) + """ + + astra_name = "SIRT-PLUGIN" + + def initialize(self,cfg, Relaxation = 1, MinConstraint = None, MaxConstraint = None): + self.W = astra.OpTomo(cfg['ProjectorId']) + self.vid = cfg['ReconstructionDataId'] + self.sid = cfg['ProjectionDataId'] + self.min_constraint = MinConstraint + self.max_constraint = MaxConstraint + + try: + v = astra.data2d.get_shared(self.vid) + s = astra.data2d.get_shared(self.sid) + self.data_mod = astra.data2d + except Exception: + v = astra.data3d.get_shared(self.vid) + s = astra.data3d.get_shared(self.sid) + self.data_mod = astra.data3d + + self.R = self.W * np.ones(v.shape,dtype=np.float32).ravel(); + self.R[self.R < 0.000001] = np.Inf + self.R = 1 / self.R + self.R = self.R.reshape(s.shape) + + self.mrC = self.W.T * np.ones(s.shape,dtype=np.float32).ravel(); + self.mrC[self.mrC < 0.000001] = np.Inf + self.mrC = -Relaxation / self.mrC + self.mrC = self.mrC.reshape(v.shape) + + + def run(self, its): + v = self.data_mod.get_shared(self.vid) + s = self.data_mod.get_shared(self.sid) + tv = np.zeros(v.shape, dtype=np.float32) + ts = np.zeros(s.shape, dtype=np.float32) + W = self.W + mrC = self.mrC + R = self.R + for i in range(its): + W.FP(v,out=ts) + ts -= s + ts *= R # ts = R * (W*v - s) + + W.BP(ts,out=tv) + tv *= mrC + + v += tv # v = v - rel * C * W' * ts + + if self.min_constraint is not None or self.max_constraint is not None: + v.clip(min=self.min_constraint, max=self.max_constraint, out=v) + diff --git a/python/builder.py b/python/builder.py index dcd62d8..243888b 100644 --- a/python/builder.py +++ b/python/builder.py @@ -87,6 +87,6 @@ setup (name = 'PyASTRAToolbox', include_dirs=[np.get_include()], cmdclass = cmdclass, #ext_modules = [Extension("astra","astra/astra.pyx")], - packages=['astra'], + packages=['astra', 'astra.plugins'], requires=["numpy"], ) diff --git a/samples/python/s018_plugin.py b/samples/python/s018_plugin.py index 85b5486..f626908 100644 --- a/samples/python/s018_plugin.py +++ b/samples/python/s018_plugin.py @@ -124,6 +124,14 @@ if __name__=='__main__': # We can also use OpTomo to call the plugin rec_op = W.reconstruct('LANDWEBER-PLUGIN', sinogram, 100, extraOptions={'Relaxation':1.5}) + + # ASTRA also comes with built-in plugins: + astra.plugin.register(astra.plugins.SIRTPlugin) + astra.plugin.register(astra.plugins.CGLSPlugin) + rec_sirt = W.reconstruct('SIRT-PLUGIN', sinogram, 100, extraOptions={'Relaxation':1.5}) + rec_cgls = W.reconstruct('CGLS-PLUGIN', sinogram, 100) + + import pylab as pl pl.gray() pl.figure(1) @@ -132,6 +140,10 @@ if __name__=='__main__': pl.imshow(rec_rel,vmin=0,vmax=1) pl.figure(3) pl.imshow(rec_op,vmin=0,vmax=1) + pl.figure(4) + pl.imshow(rec_sirt,vmin=0,vmax=1) + pl.figure(5) + pl.imshow(rec_cgls,vmin=0,vmax=1) pl.show() # Clean up. |