Grangeat-based 2D/3D image registration
Loading...
Searching...
No Matches
Radon3D.h
Go to the documentation of this file.
1#pragma once
2
3#include "Common.h"
4
5namespace reg23 {
6
25at::Tensor Radon3D_CPU(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues,
26 const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection);
27
48at::Tensor DRadon3DDR_CPU(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues,
49 const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection);
50
57__host__ at::Tensor Radon3D_CUDA(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues,
58 const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection);
59
66__host__ at::Tensor Radon3D_CUDA_V2(const at::Tensor &volume, const at::Tensor &volumeSpacing,
67 const at::Tensor &phiValues, const at::Tensor &thetaValues,
68 const at::Tensor &rValues, int64_t samplesPerDirection);
69
76__host__ at::Tensor DRadon3DDR_CUDA(const at::Tensor &volume, const at::Tensor &volumeSpacing,
77 const at::Tensor &phiValues, const at::Tensor &thetaValues,
78 const at::Tensor &rValues, int64_t samplesPerDirection);
79
86__host__ at::Tensor DRadon3DDR_CUDA_V2(const at::Tensor &volume, const at::Tensor &volumeSpacing,
87 const at::Tensor &phiValues, const at::Tensor &thetaValues,
88 const at::Tensor &rValues, int64_t samplesPerDirection);
89
96template <typename texture_t> struct Radon3D {
97
98 static_assert(texture_t::DIMENSIONALITY == 3);
99
100 using IntType = typename texture_t::IntType;
101 using FloatType = typename texture_t::FloatType;
102 using SizeType = typename texture_t::SizeType;
103 using VectorType = typename texture_t::VectorType;
104 using AddressModeType = typename texture_t::AddressModeType;
105
112
113 __host__ static CommonData Common(const at::Tensor &volume, const at::Tensor &volumeSpacing,
114 const at::Tensor &phiValues, const at::Tensor &thetaValues,
115 const at::Tensor &rValues, int64_t samplesPerDirection, at::DeviceType device) {
116 // volume should be a 3D array of floats on the chosen device
117 TORCH_CHECK(volume.sizes().size() == 3);
118 TORCH_CHECK(volume.dtype() == at::kFloat);
119 TORCH_INTERNAL_ASSERT(volume.device().type() == device);
120 // volumeSpacing should be a 1D tensor of 3 doubles
121 TORCH_CHECK(volumeSpacing.sizes() == at::IntArrayRef{3});
122 TORCH_CHECK(volumeSpacing.dtype() == at::kDouble);
123 // phiValues, thetaValues and rValues should have matching sizes, contain floats, and be on the chosen device
124 TORCH_CHECK(phiValues.sizes() == thetaValues.sizes());
125 TORCH_CHECK(thetaValues.sizes() == rValues.sizes());
126 TORCH_CHECK(phiValues.dtype() == at::kFloat);
127 TORCH_CHECK(thetaValues.dtype() == at::kFloat);
128 TORCH_CHECK(rValues.dtype() == at::kFloat);
129 TORCH_INTERNAL_ASSERT(phiValues.device().type() == device);
130 TORCH_INTERNAL_ASSERT(thetaValues.device().type() == device);
131 TORCH_INTERNAL_ASSERT(rValues.device().type() == device);
132
133 CommonData ret{};
134 ret.inputTexture = texture_t::FromTensor(volume, VectorType::FromTensor(volumeSpacing));
135 const FloatType planeSize = sqrt(
136 ret.inputTexture.SizeWorld().template Apply<FloatType>(&Square<FloatType>).Sum());
137 ret.mappingIndexToOffset = GetMappingIToOffset(planeSize, samplesPerDirection);
139 ret.scaleFactor = rootScaleFactor * rootScaleFactor;
140 ret.flatOutput = torch::zeros(at::IntArrayRef({phiValues.numel()}), volume.contiguous().options());
141 return ret;
142 }
143
157
158 return {VectorType::Full(-.5 * planeSize),
159 VectorType::Full(planeSize / static_cast<FloatType>(samplesPerDirection - 1))};
160 }
161
176 const FloatType sp = sin(phi);
177 const FloatType cp = cos(phi);
178 const FloatType st = sin(theta);
179 const FloatType ct = cos(theta);
180 const Linear2<VectorType> mappingOffsetToWorld{{r * ct * cp, r * ct * sp, r * st}, {-sp, cp, 0.f},
181 {-st * cp, -st * sp, ct}};
182 return textureIn.MappingWorldToTexCoord()(mappingOffsetToWorld(mappingIToOffset));
183 }
184
199 const FloatType sign = static_cast<FloatType>(r > 0.) - static_cast<FloatType>(r < 0.);
200 const FloatType sp = sin(phi);
201 const FloatType cp = cos(phi);
202 const FloatType st = sin(theta);
203 const FloatType ct = cos(theta);
204 return textureIn.MappingWorldToTexCoord().gradient * sign * VectorType{ct * cp, ct * sp, st};
205 }
206
220 __host__ __device__ [[nodiscard]] static float
223 float ret = 0.f;
224 for (int64_t j = 0; j < samplesPerDirection; ++j) {
225 for (int64_t i = 0; i < samplesPerDirection; ++i) {
226 const FloatType iF = static_cast<FloatType>(i);
227 const FloatType jF = static_cast<FloatType>(j);
228 ret += texture.Sample(mappingIndexToTexCoord(VectorType::Full(iF), VectorType::Full(jF)));
229 }
230 }
231 return ret;
232 }
233
244 __host__ __device__ [[nodiscard]] static float
247 float ret = 0.f;
248 for (int64_t j = 0; j < samplesPerDirection; ++j) {
249 for (int64_t i = 0; i < samplesPerDirection; ++i) {
250 const FloatType iF = static_cast<FloatType>(i);
251 const FloatType jF = static_cast<FloatType>(j);
252 const VectorType texCoord = mappingIndexToTexCoord(VectorType::Full(iF), VectorType::Full(jF));
254 }
255 }
256 return ret;
257 }
258};
259
260} // namespace reg23
General tools and structs.
#define __host__
Definition Global.h:17
#define __device__
Definition Global.h:22
__host__ __device__ constexpr T VecDot(const Vec< T, N > &lhs, const Vec< T, N > &rhs)
reg23::Vec dot product
Definition Vec.h:667
at::Tensor DRadon3DDR_CPU(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues, const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection)
Compute the derivative with respect to plane-origin distance of an approximation of the Radon transfo...
Definition Radon3DCPU.cpp:31
__host__ at::Tensor Radon3D_CUDA(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues, const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection)
An implementation of reg23::Radon3D_CPU that uses CUDA parallelisation.
__host__ at::Tensor DRadon3DDR_CUDA(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues, const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection)
An implementation of reg23::DRadon3DDR_CPU that uses CUDA parallelisation.
at::Tensor Radon3D_CPU(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues, const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection)
Compute an approximation of the Radon transform of the given 3D volume.
Definition Radon3DCPU.cpp:10
Vec< TextureAddressMode, DIMENSIONALITY > StringsToAddressModes(const std::array< std::string_view, DIMENSIONALITY > &strings)
Definition Texture.h:44
Definition GridSample3DCPU.cpp:6
__host__ at::Tensor DRadon3DDR_CUDA_V2(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues, const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection)
An implementation of reg23::DRadon3DDR_CPU that uses CUDA parallelisation.
__host__ at::Tensor Radon3D_CUDA_V2(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues, const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection)
An implementation of reg23::Radon3D_CPU that uses CUDA parallelisation.
A functor class that represents a linear transformation of two variables: intercept + gradient1 * x +...
Definition Common.h:59
A functor class that represents a linear transformation: intercept + gradient * x.
Definition Common.h:27
Definition Radon3D.h:106
texture_t inputTexture
Definition Radon3D.h:107
FloatType scaleFactor
Definition Radon3D.h:109
Linear< VectorType > mappingIndexToOffset
Definition Radon3D.h:108
at::Tensor flatOutput
Definition Radon3D.h:110
Definition Radon3D.h:96
__host__ static __device__ float DIntegrateLoopedDMappingParameter(const texture_t &texture, const Linear2< VectorType > &mappingIndexToTexCoord, const VectorType &dTexCoordDMappingParameter, int64_t samplesPerDirection)
Definition Radon3D.h:245
typename texture_t::IntType IntType
Definition Radon3D.h:100
typename texture_t::FloatType FloatType
Definition Radon3D.h:101
__host__ static __device__ Linear2< VectorType > GetMappingIndexToTexCoord(const texture_t &textureIn, FloatType phi, FloatType theta, FloatType r, const Linear< VectorType > &mappingIToOffset)
Definition Radon3D.h:174
__host__ static __device__ float IntegrateLooped(const texture_t &texture, const Linear2< VectorType > &mappingIndexToTexCoord, int64_t samplesPerDirection)
Definition Radon3D.h:221
__host__ static __device__ Linear< VectorType > GetMappingIToOffset(FloatType planeSize, int64_t samplesPerDirection)
Definition Radon3D.h:155
typename texture_t::VectorType VectorType
Definition Radon3D.h:103
typename texture_t::SizeType SizeType
Definition Radon3D.h:102
typename texture_t::AddressModeType AddressModeType
Definition Radon3D.h:104
static __host__ CommonData Common(const at::Tensor &volume, const at::Tensor &volumeSpacing, const at::Tensor &phiValues, const at::Tensor &thetaValues, const at::Tensor &rValues, int64_t samplesPerDirection, at::DeviceType device)
Definition Radon3D.h:113
__host__ static __device__ VectorType GetDTexCoordDR(const texture_t &textureIn, FloatType phi, FloatType theta, FloatType r)
Definition Radon3D.h:197