1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
|
# -----------------------------------------------------------------------
# Copyright: 2010-2022, imec Vision Lab, University of Antwerp
# 2013-2022, CWI, Amsterdam
#
# Contact: astra@astra-toolbox.com
# Website: http://www.astra-toolbox.com/
#
# 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/>.
#
# -----------------------------------------------------------------------
#
# distutils: language = c++
# distutils: libraries = astra
include "config.pxi"
from . cimport utils
from .utils import wrap_from_bytes
from .utils cimport createProjectionGeometry3D
from .log import AstraError
IF HAVE_CUDA==True:
from .PyIncludes cimport *
from libcpp.vector cimport vector
cdef extern from "astra/Filters.h" namespace "astra":
cdef enum E_FBPFILTER:
FILTER_ERROR
FILTER_NONE
FILTER_RAMLAK
cdef cppclass SFilterConfig:
SFilterConfig()
E_FBPFILTER m_eType
cdef extern from "astra/CompositeGeometryManager.h" namespace "astra::CCompositeGeometryManager":
cdef enum EJobMode:
MODE_ADD
MODE_SET
cdef extern from "astra/CompositeGeometryManager.h" namespace "astra":
cdef cppclass CCompositeGeometryManager:
bool doFP(CProjector3D *, vector[CFloat32VolumeData3D *], vector[CFloat32ProjectionData3D *], EJobMode) nogil
bool doBP(CProjector3D *, vector[CFloat32VolumeData3D *], vector[CFloat32ProjectionData3D *], EJobMode) nogil
bool doFDK(CProjector3D *, CFloat32VolumeData3D *, CFloat32ProjectionData3D *, bool, SFilterConfig &, EJobMode) nogil
cdef extern from *:
CFloat32VolumeData3D * dynamic_cast_vol_mem "dynamic_cast<astra::CFloat32VolumeData3D*>" (CData3D * )
CFloat32ProjectionData3D * dynamic_cast_proj_mem "dynamic_cast<astra::CFloat32ProjectionData3D*>" (CData3D * )
from . cimport PyProjector3DManager
from .PyProjector3DManager cimport CProjector3DManager
from . cimport PyData3DManager
from .PyData3DManager cimport CData3DManager
cdef CProjector3DManager * manProj = <CProjector3DManager * >PyProjector3DManager.getSingletonPtr()
cdef CData3DManager * man3d = <CData3DManager * >PyData3DManager.getSingletonPtr()
def do_composite(projector_id, vol_ids, proj_ids, mode, t):
if mode != MODE_ADD and mode != MODE_SET:
raise AstraError("Internal error: wrong composite mode")
cdef EJobMode eMode = mode;
cdef vector[CFloat32VolumeData3D *] vol
cdef CFloat32VolumeData3D * pVolObject
cdef CFloat32ProjectionData3D * pProjObject
for v in vol_ids:
pVolObject = dynamic_cast_vol_mem(man3d.get(v))
if pVolObject == NULL:
raise AstraError("Data object not found")
if not pVolObject.isInitialized():
raise AstraError("Data object not initialized properly")
vol.push_back(pVolObject)
cdef vector[CFloat32ProjectionData3D *] proj
for v in proj_ids:
pProjObject = dynamic_cast_proj_mem(man3d.get(v))
if pProjObject == NULL:
raise AstraError("Data object not found")
if not pProjObject.isInitialized():
raise AstraError("Data object not initialized properly")
proj.push_back(pProjObject)
cdef CCompositeGeometryManager m
cdef CProjector3D * projector = manProj.get(projector_id) # may be NULL
cdef bool ret = True
if t == "FP":
with nogil:
ret = m.doFP(projector, vol, proj, eMode)
if not ret:
raise AstraError("Failed to perform FP", append_log=True)
elif t == "BP":
with nogil:
ret = m.doBP(projector, vol, proj, eMode)
if not ret:
raise AstraError("Failed to perform BP", append_log=True)
else:
raise AstraError("Internal error: wrong composite op type")
def do_composite_FP(projector_id, vol_ids, proj_ids):
do_composite(projector_id, vol_ids, proj_ids, MODE_SET, "FP")
def do_composite_BP(projector_id, vol_ids, proj_ids):
do_composite(projector_id, vol_ids, proj_ids, MODE_SET, "BP")
def accumulate_FP(projector_id, vol_id, proj_id):
do_composite(projector_id, [vol_id], [proj_id], MODE_ADD, "FP")
def accumulate_BP(projector_id, vol_id, proj_id):
do_composite(projector_id, [vol_id], [proj_id], MODE_ADD, "BP")
def accumulate_FDK(projector_id, vol_id, proj_id):
cdef CFloat32VolumeData3D * pVolObject
cdef CFloat32ProjectionData3D * pProjObject
pVolObject = dynamic_cast_vol_mem(man3d.get(vol_id))
if pVolObject == NULL:
raise AstraError("Data object not found")
if not pVolObject.isInitialized():
raise AstraError("Data object not initialized properly")
pProjObject = dynamic_cast_proj_mem(man3d.get(proj_id))
if pProjObject == NULL:
raise AstraError("Data object not found")
if not pProjObject.isInitialized():
raise AstraError("Data object not initialized properly")
cdef CCompositeGeometryManager m
cdef CProjector3D * projector = manProj.get(projector_id) # may be NULL
cdef SFilterConfig filterConfig
filterConfig.m_eType = FILTER_RAMLAK
cdef bool ret = True
with nogil:
ret = m.doFDK(projector, pVolObject, pProjObject, False, filterConfig, MODE_ADD)
if not ret:
raise AstraError("Failed to perform FDK", append_log=True)
from . cimport utils
from .utils cimport linkVolFromGeometry, linkProjFromGeometry
def direct_FPBP3D(projector_id, vol, proj, mode, t):
if mode != MODE_ADD and mode != MODE_SET:
raise AstraError("Internal error: wrong composite mode")
cdef EJobMode eMode = mode
cdef CProjector3D * projector = manProj.get(projector_id)
if projector == NULL:
raise AstraError("Projector not found")
cdef CFloat32VolumeData3D * pVol = linkVolFromGeometry(projector.getVolumeGeometry(), vol)
cdef CFloat32ProjectionData3D * pProj = linkProjFromGeometry(projector.getProjectionGeometry(), proj)
cdef vector[CFloat32VolumeData3D *] vols
cdef vector[CFloat32ProjectionData3D *] projs
vols.push_back(pVol)
projs.push_back(pProj)
cdef CCompositeGeometryManager m
cdef bool ret = True
try:
if t == "FP":
with nogil:
ret = m.doFP(projector, vols, projs, eMode)
if not ret:
AstraError("Failed to perform FP", append_log=True)
elif t == "BP":
with nogil:
ret = m.doBP(projector, vols, projs, eMode)
if not ret:
AstraError("Failed to perform BP", append_log=True)
else:
AstraError("Internal error: wrong op type")
finally:
del pVol
del pProj
def direct_FP3D(projector_id, vol, proj):
"""Perform a 3D forward projection with pre-allocated input/output.
:param projector_id: A 3D projector object handle
:type datatype: :class:`int`
:param vol: The input data, as either a numpy array, or a GPULink object
:type datatype: :class:`numpy.ndarray` or :class:`astra.data3d.GPULink`
:param proj: The pre-allocated output data, either numpy array or GPULink
:type datatype: :class:`numpy.ndarray` or :class:`astra.data3d.GPULink`
"""
direct_FPBP3D(projector_id, vol, proj, MODE_SET, "FP")
def direct_BP3D(projector_id, vol, proj):
"""Perform a 3D back projection with pre-allocated input/output.
:param projector_id: A 3D projector object handle
:type datatype: :class:`int`
:param vol: The pre-allocated output data, as either a numpy array, or a GPULink object
:type datatype: :class:`numpy.ndarray` or :class:`astra.data3d.GPULink`
:param proj: The input data, either numpy array or GPULink
:type datatype: :class:`numpy.ndarray` or :class:`astra.data3d.GPULink`
"""
direct_FPBP3D(projector_id, vol, proj, MODE_SET, "BP")
def getProjectedBBox(geometry, minx, maxx, miny, maxy, minz, maxz):
cdef unique_ptr[CProjectionGeometry3D] ppGeometry
cdef double minu=0., maxu=0., minv=0., maxv=0.
ppGeometry = createProjectionGeometry3D(geometry)
ppGeometry.get().getProjectedBBox(minx, maxx, miny, maxy, minz, maxz, minu, maxu, minv, maxv)
return (minv, maxv)
def projectPoint(geometry, x, y, z, angle):
cdef unique_ptr[CProjectionGeometry3D] ppGeometry
cdef double u=0., v=0.
ppGeometry = createProjectionGeometry3D(geometry)
ppGeometry.get().projectPoint(x, y, z, angle, u, v)
return (u, v)
|