Grangeat-based 2D/3D image registration
Loading...
Searching...
No Matches
Radon2D.h
Go to the documentation of this file.
1
6#pragma once
7
8#include "Common.h"
9
10namespace reg23 {
11
27at::Tensor Radon2D_CPU(const at::Tensor &image, const at::Tensor &imageSpacing, const at::Tensor &phiValues,
28 const at::Tensor &rValues, int64_t samplesPerLine);
29
47at::Tensor DRadon2DDR_CPU(const at::Tensor &image, const at::Tensor &imageSpacing, const at::Tensor &phiValues,
48 const at::Tensor &rValues, int64_t samplesPerLine);
49
56__host__ at::Tensor Radon2D_CUDA(const at::Tensor &image, const at::Tensor &imageSpacing, const at::Tensor &phiValues,
57 const at::Tensor &rValues, int64_t samplesPerLine);
58
65__host__ at::Tensor Radon2D_CUDA_V2(const at::Tensor &image, const at::Tensor &imageSpacing,
66 const at::Tensor &phiValues, const at::Tensor &rValues, int64_t samplesPerLine);
67
74__host__ at::Tensor DRadon2DDR_CUDA(const at::Tensor &image, const at::Tensor &imageSpacing,
75 const at::Tensor &phiValues, const at::Tensor &rValues, int64_t samplesPerLine);
76
83template <typename texture_t> struct Radon2D {
84
85 static_assert(texture_t::DIMENSIONALITY == 2);
86
87 using IntType = typename texture_t::IntType;
88 using FloatType = typename texture_t::FloatType;
89 using SizeType = typename texture_t::SizeType;
90 using VectorType = typename texture_t::VectorType;
91 using AddressModeType = typename texture_t::AddressModeType;
92
99
100 __host__ static CommonData Common(const at::Tensor &image, const at::Tensor &imageSpacing,
101 const at::Tensor &phiValues, const at::Tensor &rValues, int64_t samplesPerLine,
102 at::DeviceType device) {
103 // image should be a 2D tensor of floats on the chosen device
104 TORCH_CHECK(image.sizes().size() == 2);
105 TORCH_CHECK(image.dtype() == at::kFloat);
106 TORCH_INTERNAL_ASSERT(image.device().type() == device);
107 // imageSpacing should be a 1D tensor of 2 doubles
108 TORCH_CHECK(imageSpacing.sizes() == at::IntArrayRef{2});
109 TORCH_CHECK(imageSpacing.dtype() == at::kDouble);
110 // phiValues and rValues should have the same sizes, should contain floats, and be on the chosen device
111 TORCH_CHECK(phiValues.sizes() == rValues.sizes());
112 TORCH_CHECK(phiValues.dtype() == at::kFloat);
113 TORCH_CHECK(rValues.dtype() == at::kFloat);
114 TORCH_INTERNAL_ASSERT(phiValues.device().type() == device);
115 TORCH_INTERNAL_ASSERT(rValues.device().type() == device);
116
117 CommonData ret{};
118 ret.inputTexture = texture_t::FromTensor(image, VectorType::FromTensor(imageSpacing));
119 const FloatType lineLength = sqrt(
120 ret.inputTexture.SizeWorld().template Apply<FloatType>(&Square<FloatType>).Sum());
121 ret.mappingIndexToOffset = GetMappingIToOffset(lineLength, samplesPerLine);
122 ret.scaleFactor = lineLength / static_cast<float>(samplesPerLine);
123 ret.flatOutput = torch::zeros(at::IntArrayRef({phiValues.numel()}), image.contiguous().options());
124 return ret;
125 }
126
140 return {VectorType::Full(-.5f * lineLength),
141 VectorType::Full(lineLength / static_cast<FloatType>(samplesPerLine - 1))};
142 }
143
157 const FloatType s = sin(phi);
158 const FloatType c = cos(phi);
159 const Linear<VectorType> mappingOffsetToWorld{{r * c, r * s}, {-s, c}};
160 return textureIn.MappingWorldToTexCoord()(mappingOffsetToWorld(mappingIToOffset));
161 }
162
175 FloatType r) {
176 const FloatType sign = static_cast<FloatType>(r > 0.) - static_cast<FloatType>(r < 0.);
177 const FloatType s = sin(phi);
178 const FloatType c = cos(phi);
179 return textureIn.MappingWorldToTexCoord().gradient * sign * VectorType{c, s};
180 }
181
194 __host__ __device__ [[nodiscard]] static float IntegrateLooped(const texture_t &texture,
197 float ret = 0.f;
198 for (int64_t i = 0; i < samplesPerLine; ++i) {
199 const FloatType iF = static_cast<FloatType>(i);
200 ret += texture.Sample(mappingIndexToTexCoord(VectorType::Full(iF)));
201 }
202 return ret;
203 }
204
215 __host__ __device__ [[nodiscard]] static float
218 float ret = 0.f;
219 for (int64_t i = 0; i < samplesPerLine; ++i) {
220 const FloatType iF = static_cast<FloatType>(i);
221 const VectorType texCoord = mappingIndexToTexCoord(VectorType::Full(iF));
223 }
224 return ret;
225 }
226};
227
228} // 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
__host__ at::Tensor DRadon2DDR_CUDA(const at::Tensor &image, const at::Tensor &imageSpacing, const at::Tensor &phiValues, const at::Tensor &rValues, int64_t samplesPerLine)
An implementation of reg23::DRadon2DDR_CPU that uses CUDA parallelisation.
__host__ at::Tensor Radon2D_CUDA(const at::Tensor &image, const at::Tensor &imageSpacing, const at::Tensor &phiValues, const at::Tensor &rValues, int64_t samplesPerLine)
An implementation of reg23::Radon2D_CPU that uses CUDA parallelisation.
at::Tensor Radon2D_CPU(const at::Tensor &image, const at::Tensor &imageSpacing, const at::Tensor &phiValues, const at::Tensor &rValues, int64_t samplesPerLine)
Compute an approximation of the Radon transform of the given 2D image.
Definition Radon2DCPU.cpp:15
at::Tensor DRadon2DDR_CPU(const at::Tensor &image, const at::Tensor &imageSpacing, const at::Tensor &phiValues, const at::Tensor &rValues, int64_t samplesPerLine)
Compute the derivative with respect to plane-origin distance of an approximation of the Radon transfo...
Definition Radon2DCPU.cpp:33
Vec< TextureAddressMode, DIMENSIONALITY > StringsToAddressModes(const std::array< std::string_view, DIMENSIONALITY > &strings)
Definition Texture.h:44
Definition GridSample3DCPU.cpp:6
__host__ at::Tensor Radon2D_CUDA_V2(const at::Tensor &image, const at::Tensor &imageSpacing, const at::Tensor &phiValues, const at::Tensor &rValues, int64_t samplesPerLine)
An implementation of reg23::Radon2D_CPU that uses CUDA parallelisation.
A functor class that represents a linear transformation: intercept + gradient * x.
Definition Common.h:27
Definition Radon2D.h:93
FloatType scaleFactor
Definition Radon2D.h:96
at::Tensor flatOutput
Definition Radon2D.h:97
Linear< VectorType > mappingIndexToOffset
Definition Radon2D.h:95
texture_t inputTexture
Definition Radon2D.h:94
Definition Radon2D.h:83
__host__ static __device__ VectorType GetDTexCoordDR(const texture_t &textureIn, FloatType phi, FloatType r)
Definition Radon2D.h:174
__host__ static __device__ Linear< VectorType > GetMappingIndexToTexCoord(const texture_t &textureIn, FloatType phi, FloatType r, const Linear< VectorType > &mappingIToOffset)
Definition Radon2D.h:155
typename texture_t::SizeType SizeType
Definition Radon2D.h:89
__host__ static __device__ float IntegrateLooped(const texture_t &texture, const Linear< VectorType > &mappingIndexToTexCoord, int64_t samplesPerLine)
Definition Radon2D.h:194
typename texture_t::IntType IntType
Definition Radon2D.h:87
__host__ static __device__ float DIntegrateLoopedDMappingParameter(const texture_t &texture, const Linear< VectorType > &mappingIndexToTexCoord, const VectorType &dTexCoordDMappingParameter, int64_t samplesPerLine)
Definition Radon2D.h:216
static __host__ CommonData Common(const at::Tensor &image, const at::Tensor &imageSpacing, const at::Tensor &phiValues, const at::Tensor &rValues, int64_t samplesPerLine, at::DeviceType device)
Definition Radon2D.h:100
typename texture_t::VectorType VectorType
Definition Radon2D.h:90
__host__ static __device__ Linear< VectorType > GetMappingIToOffset(FloatType lineLength, int64_t samplesPerLine)
Definition Radon2D.h:138
typename texture_t::FloatType FloatType
Definition Radon2D.h:88
typename texture_t::AddressModeType AddressModeType
Definition Radon2D.h:91