Grangeat-based 2D/3D image registration
Loading...
Searching...
No Matches
Texture3DCPU.h
Go to the documentation of this file.
1#pragma once
2
3#include "Texture.h"
4
5namespace reg23 {
6
15class Texture3DCPU : public Texture<3, int64_t, double> {
16public:
18
19 Texture3DCPU() = default;
20
27
28 // yes copy
29 Texture3DCPU(const Texture3DCPU &) = default;
30
31 Texture3DCPU &operator=(const Texture3DCPU &) = default;
32
33 // yes move
35
37
45 static Texture3DCPU FromTensor(const at::Tensor &volume, VectorType spacing,
46 VectorType centrePosition = VectorType::Full(0),
48 return {volume.contiguous().data_ptr<float>(), Vec<int64_t, 3>::FromIntArrayRef(volume.sizes()).Flipped(),
49 std::move(spacing), std::move(centrePosition), std::move(addressModes)};
50 }
51
56 [[nodiscard]] __host__ __device__ float At(const SizeType &index) const {
57 if ((addressModes.X() == TextureAddressMode::ZERO && (index.X() < 0 || index.X() >= Size().X())) || (
58 addressModes.Y() == TextureAddressMode::ZERO && (index.Y() < 0 || index.Y() >= Size().Y())) || (
59 addressModes.Z() == TextureAddressMode::ZERO && (index.Z() < 0 || index.Z() >= Size().Z()))) {
60 return 0.f;
61 }
62 // Uses wrapping for indices outside the texture.
63 return ptr[Modulo(index.Z(), Size().Z()) * Size().X() * Size().Y() + Modulo(index.Y(), Size().Y()) * Size().X()
64 + Modulo(index.X(), Size().X())];
65 }
66
72 texCoord = texCoord * Size().StaticCast<double>() - .5;
73 const VectorType floored = texCoord.Apply<double>(&floor);
74 const SizeType index = floored.StaticCast<int64_t>();
76 const float l0r0 = (1.f - fractions.X()) * At(index) + fractions.X() *
77 At({index.X() + 1, index.Y(), index.Z()});
78 const float l0r1 = (1.f - fractions.X()) * At({index.X(), index.Y() + 1, index.Z()}) + fractions.X() * At(
79 {index.X() + 1, index.Y() + 1, index.Z()});
80 const float l1r0 = (1.f - fractions.X()) * At({index.X(), index.Y(), index.Z() + 1}) + fractions.X() * At(
81 {index.X() + 1, index.Y(), index.Z() + 1});
82 const float l1r1 = (1.f - fractions.X()) * At({index.X(), index.Y() + 1, index.Z() + 1}) + fractions.X() * At(
83 {index.X() + 1, index.Y() + 1, index.Z() + 1});
84 const float l0 = (1.f - fractions.Y()) * l0r0 + fractions.Y() * l0r1;
85 const float l1 = (1.f - fractions.Y()) * l1r0 + fractions.Y() * l1r1;
86 return (1.f - fractions.Z()) * l0 + fractions.Z() * l1;
87 }
88
95 const VectorType sizeF = Size().StaticCast<double>();
96 texCoord = texCoord * sizeF - .5;
97 const VectorType floored = texCoord.Apply<double>(&floor);
98 const SizeType index = floored.StaticCast<int64_t>();
99 const float fVertical = texCoord.Y() - floored.Y();
100 const float fInward = texCoord.Z() - floored.Z();
101 const float l0 = (1.f - fVertical) * (At({index.X() + 1, index.Y(), index.Z()}) - At(index)) + fVertical * (
102 At({index.X() + 1, index.Y() + 1, index.Z()}) - At({index.X(), index.Y() + 1, index.Z()}));
103 const float l1 = (1.f - fVertical) * (At({index.X() + 1, index.Y(), index.Z() + 1}) -
104 At({index.X(), index.Y(), index.Z() + 1})) + fVertical * (
105 At({index.X() + 1, index.Y() + 1, index.Z() + 1}) - At(
106 {index.X(), index.Y() + 1, index.Z() + 1}));
107 return sizeF.X() * ((1.f - fInward) * l0 + fInward * l1);
108 }
109
116 const VectorType sizeF = Size().StaticCast<double>();
117 texCoord = texCoord * sizeF - .5;
118 const VectorType floored = texCoord.Apply<double>(&floor);
119 const SizeType index = floored.StaticCast<int64_t>();
120 const float fHorizontal = texCoord.X() - floored.X();
121 const float fInward = texCoord.Z() - floored.Z();
122 const float l0 = (1.f - fHorizontal) * (At({index.X(), index.Y() + 1, index.Z()}) - At(index)) + fHorizontal * (
123 At({index.X() + 1, index.Y() + 1, index.Z()}) - At({index.X() + 1, index.Y(), index.Z()}));
124 const float l1 = (1.f - fHorizontal) * (At({index.X(), index.Y() + 1, index.Z() + 1}) -
125 At({index.X(), index.Y(), index.Z() + 1})) + fHorizontal * (
126 At({index.X() + 1, index.Y() + 1, index.Z() + 1}) - At(
127 {index.X() + 1, index.Y(), index.Z() + 1}));
128 return sizeF.Y() * ((1.f - fInward) * l0 + fInward * l1);
129 }
130
137 const VectorType sizeF = Size().StaticCast<double>();
138 texCoord = texCoord * sizeF - .5;
139 const VectorType floored = texCoord.Apply<double>(&floor);
140 const SizeType index = floored.StaticCast<int64_t>();
141 const float fHorizontal = texCoord.X() - floored.X();
142 const float fVertical = texCoord.Y() - floored.Y();
143 const float r0 = (1.f - fHorizontal) * (At({index.X(), index.Y(), index.Z() + 1}) - At(index)) + fHorizontal * (
144 At({index.X() + 1, index.Y(), index.Z() + 1}) - At({index.X() + 1, index.Y(), index.Z()}));
145 const float r1 = (1.f - fHorizontal) * (At({index.X(), index.Y() + 1, index.Z() + 1}) -
146 At({index.X(), index.Y() + 1, index.Z()})) + fHorizontal * (
147 At({index.X() + 1, index.Y() + 1, index.Z() + 1}) - At(
148 {index.X() + 1, index.Y() + 1, index.Z()}));
149 return sizeF.Z() * ((1.f - fVertical) * r0 + fVertical * r1);
150 }
151
158 const VectorType sizeF = Size().StaticCast<double>();
159 texCoord = texCoord * sizeF - .5;
160 const VectorType floored = texCoord.Apply<double>(&floor);
161 const SizeType index = floored.StaticCast<int64_t>();
162 const float fHorizontal = texCoord.X() - floored.X();
163 const float fVertical = texCoord.Y() - floored.Y();
164 const float fInward = texCoord.Z() - floored.Z();
165
166 // x-direction
167 const float x0 = (1.f - fVertical) * (At({index.X() + 1, index.Y(), index.Z()}) - At(index)) + fVertical * (
168 At({index.X() + 1, index.Y() + 1, index.Z()}) - At({index.X(), index.Y() + 1, index.Z()}));
169 const float x1 = (1.f - fVertical) * (At({index.X() + 1, index.Y(), index.Z() + 1}) -
170 At({index.X(), index.Y(), index.Z() + 1})) + fVertical * (
171 At({index.X() + 1, index.Y() + 1, index.Z() + 1}) - At(
172 {index.X(), index.Y() + 1, index.Z() + 1}));
173
174 // y-direction
175 const float y0 = (1.f - fHorizontal) * (At({index.X(), index.Y() + 1, index.Z()}) - At(index)) + fHorizontal * (
176 At({index.X() + 1, index.Y() + 1, index.Z()}) - At({index.X() + 1, index.Y(), index.Z()}));
177 const float y1 = (1.f - fHorizontal) * (At({index.X(), index.Y() + 1, index.Z() + 1}) -
178 At({index.X(), index.Y(), index.Z() + 1})) + fHorizontal * (
179 At({index.X() + 1, index.Y() + 1, index.Z() + 1}) - At(
180 {index.X() + 1, index.Y(), index.Z() + 1}));
181
182 // z-direction
183
184 const float z0 = (1.f - fHorizontal) * (At({index.X(), index.Y(), index.Z() + 1}) - At(index)) + fHorizontal * (
185 At({index.X() + 1, index.Y(), index.Z() + 1}) - At({index.X() + 1, index.Y(), index.Z()}));
186 const float z1 = (1.f - fHorizontal) * (At({index.X(), index.Y() + 1, index.Z() + 1}) -
187 At({index.X(), index.Y() + 1, index.Z()})) + fHorizontal * (
188 At({index.X() + 1, index.Y() + 1, index.Z() + 1}) - At(
189 {index.X() + 1, index.Y() + 1, index.Z()}));
190
191 return {sizeF.X() * ((1.f - fInward) * x0 + fInward * x1), //
192 sizeF.Y() * ((1.f - fInward) * y0 + fInward * y1), //
193 sizeF.Z() * ((1.f - fVertical) * z0 + fVertical * z1)};
194 }
195
196private:
197 const float *ptr{};
198 AddressModeType addressModes{};
199};
200
201} // namespace reg23
#define __host__
Definition Global.h:17
#define __device__
Definition Global.h:22
A 3D texture stored for access by the CPU.
Definition Texture3DCPU.h:15
__host__ __device__ float Sample(VectorType texCoord) const
Definition Texture3DCPU.h:71
__host__ __device__ VectorType DSampleDTexCoord(VectorType texCoord) const
Definition Texture3DCPU.h:157
static Texture3DCPU FromTensor(const at::Tensor &volume, VectorType spacing, VectorType centrePosition=VectorType::Full(0), AddressModeType addressModes=AddressModeType::Full(TextureAddressMode::ZERO))
Definition Texture3DCPU.h:45
Texture3DCPU & operator=(const Texture3DCPU &)=default
__host__ __device__ float At(const SizeType &index) const
Definition Texture3DCPU.h:56
Texture3DCPU & operator=(Texture3DCPU &&)=default
Texture3DCPU(const float *_ptr, SizeType _size, VectorType _spacing=VectorType::Full(1.), VectorType _centrePosition=VectorType::Full(0), AddressModeType _addressModes=AddressModeType::Full(TextureAddressMode::ZERO))
Definition Texture3DCPU.h:21
Texture3DCPU(Texture3DCPU &&)=default
Texture3DCPU(const Texture3DCPU &)=default
__host__ __device__ float DSampleDX(VectorType texCoord) const
Definition Texture3DCPU.h:94
__host__ __device__ float DSampleDY(VectorType texCoord) const
Definition Texture3DCPU.h:115
__host__ __device__ float DSampleDZ(VectorType texCoord) const
Definition Texture3DCPU.h:136
Texture3DCPU()=default
A parent texture class containing template data and functionality.
Definition Texture.h:71
__host__ __device__ const SizeType & Size() const
Definition Texture.h:82
Vec< TextureAddressMode, dimensionality > AddressModeType
Definition Texture.h:78
__host__ __device__ constexpr Vec< newT, N > StaticCast() const
Construct a Vec with the elements form this one cast to a new type.
Definition Vec.h:237
__host__ __device__ constexpr Vec< newT, N > Apply(const std::function< newT(T)> &f) const
Map all elements with a common std::function mapping function.
Definition Vec.h:285
__host__ __device__ constexpr const T & X() const
Get a constant reference to the first element.
Definition Vec.h:417
__host__ __device__ constexpr const T & Z() const
Get a constant reference to the third element.
Definition Vec.h:443
__host__ __device__ constexpr const T & Y() const
Get a constant reference to the second element.
Definition Vec.h:427
__host__ static __device__ constexpr Vec Full(const double &value)
Construct a Vec, copying the given value into every element.
Definition Vec.h:64
__host__ __device__ T Modulo(const T &x, const T &y)
Modulo operation that respect the sign.
Definition Global.h:48
Vec< TextureAddressMode, DIMENSIONALITY > StringsToAddressModes(const std::array< std::string_view, DIMENSIONALITY > &strings)
Definition Texture.h:44
@ ZERO
Sampling locations outside texture coordinate range will be read as 0.
Definition GridSample3DCPU.cpp:6