ML Reference
mlSubImageBox.h
Go to the documentation of this file.
1/*************************************************************************************
2**
3** Copyright 2007, MeVis Medical Solutions AG
4**
5** The user may use this file in accordance with the license agreement provided with
6** the Software or, alternatively, in accordance with the terms contained in a
7** written agreement between the user and MeVis Medical Solutions AG.
8**
9** For further information use the contact form at https://www.mevislab.de/contact
10**
11**************************************************************************************/
12
13#ifndef ML_SUB_IMAGE_BOX_H
14#define ML_SUB_IMAGE_BOX_H
15
18
19//ML-includes
20#include "mlInitSystemML.h"
21#include "mlImageVector.h"
22
23ML_START_NAMESPACE
24
25//-------------------------------------------------------------------------
51//-------------------------------------------------------------------------
52template<typename intT> class TSubImageBox
53{
54
55public:
58
64
70
71 //------------------------------------------------------
74 //------------------------------------------------------
77 inline TSubImageBox() : v1(0), v2(-1)
78 {
79 }
80
84 inline TSubImageBox(const VectorType& vector1, const VectorType& vector2) : v1(vector1), v2(vector2)
85 {
86 }
87
90 inline TSubImageBox(const VectorType extent) : v1(0), v2(extent-1)
91 {
92 }
93
94
95
96
97 //------------------------------------------------------
100 //------------------------------------------------------
102 bool operator==(const TSubImageBox<intT>& box) const
103 {
104 return (v1==box.v1) && (v2==box.v2);
105 }
106
108 bool operator!=(const TSubImageBox<intT>& box) const
109 {
110 return (v1!=box.v1) || (v2!=box.v2);
111 }
112
116 bool isEmpty() const
117 {
118 return (v1.x>v2.x) || (v1.y>v2.y) || (v1.z>v2.z) || (v1.c>v2.c) || (v1.t>v2.t) || (v1.u>v2.u);
119 }
120
123 intT getNumVoxels() const
124 {
125 if (isEmpty())
126 {
127 return 0;
128 }
129 else
130 {
131 return VectorType::compMul((v2-v1)+VectorType(1));
132 }
133 }
134
138 {
139 if (isEmpty())
140 {
141 return VectorType(0);
142 }
143 else
144 {
145 return (v2-v1)+VectorType(1);
146 }
147 }
148
149
152 void correct();
154
155
156
157 //------------------------------------------------------
160 //------------------------------------------------------
165 [[nodiscard]]
167
172
176 {
177 v1.set(0);
178 v2.set(-1);
179 }
180
182 [[nodiscard]]
184 {
185 return TSubImageBox<intT>::intersect(*this, box);
186 }
187
189 [[nodiscard]]
191 {
192 return TSubImageBox<intT>::merge(*this, box);
193 }
194
197 VectorType clamp(const VectorType& position) const;
198
200 inline bool contains (const VectorType& position) const
201 {
202 return (position >= v1) && (position <= v2);
203 }
204
206 inline void translate(const VectorType& offsetVector)
207 {
208 v1 = v1+offsetVector;
209 v2 = v2+offsetVector;
210 }
211
215 static void get3DCorners(const TSubImageBox<intT>& box, VectorType corners[8])
216 {
217 if (box.isEmpty()){
218 for (int c=0; c < 8; c++){ corners[c] = ImageVector(0); }
219 }
220 else{
221 corners[0] = box.v1;
222 corners[1] = ImageVector(box.v1.x, box.v1.y, box.v2.z,0,0,0);
223 corners[2] = ImageVector(box.v1.x, box.v2.y, box.v1.z,0,0,0);
224 corners[3] = ImageVector(box.v1.x, box.v2.y, box.v2.z,0,0,0);
225 corners[4] = ImageVector(box.v2.x, box.v1.y, box.v1.z,0,0,0);
226 corners[5] = ImageVector(box.v2.x, box.v1.y, box.v2.z,0,0,0);
227 corners[6] = ImageVector(box.v2.x, box.v2.y, box.v1.z,0,0,0);
228 corners[7] = box.v2;
229 }
230 }
231
233};
234
235ML_END_NAMESPACE
236
237//-----------------------------------------------------------------------------------
238// Stream output for std::ostream
239//-----------------------------------------------------------------------------------
240namespace std {
241
243 template <typename intT>
244 inline ostream& operator<<(ostream& s, const ML_NAMESPACE::TSubImageBox<intT> &box)
245 {
246 return s << box.v1 << " " << box.v2;
247 }
248
249}
250
251
252ML_START_NAMESPACE
253
256
257//------------------------------------------------------
258// IMPLEMENTATION: Now only internal code follows
259//------------------------------------------------------
260
261// Swaps all components where v1.* > v2.*. This is, an empty vector becomes non-empty
262// if corresponding components are not equal.
263template <typename intT>
265{
266 // Move lesser components into v1 and greater components into v2
267 VectorType V1(v1);
268 VectorType V2(v2);
269 if (V1.x<V2.x){ v1.x=V1.x; v2.x=V2.x; } else{ v1.x=V2.x; v2.x=V1.x; }
270 if (V1.y<V2.y){ v1.y=V1.y; v2.y=V2.y; } else{ v1.y=V2.y; v2.y=V1.y; }
271 if (V1.z<V2.z){ v1.z=V1.z; v2.z=V2.z; } else{ v1.z=V2.z; v2.z=V1.z; }
272 if (V1.c<V2.c){ v1.c=V1.c; v2.c=V2.c; } else{ v1.c=V2.c; v2.c=V1.c; }
273 if (V1.t<V2.t){ v1.t=V1.t; v2.t=V2.t; } else{ v1.t=V2.t; v2.t=V1.t; }
274 if (V1.u<V2.u){ v1.u=V1.u; v2.u=V2.u; } else{ v1.u=V2.u; v2.u=V1.u; }
275}
276
277// Returns the overlapping region of subimage regions \p loc1 and \p loc2.
278// A result with (v1.x>v2.x || ... || v1.z>v1.z) is interpreted as empty.
279// See also isEmpty(). This is especially true if that already
280// holds for \p loc1 or \p loc2.
281template <typename intT>
283{
284 TSubImageBox<intT> result;
285 result.v1 = VectorType::compMax(loc1.v1,loc2.v1);
286 result.v2 = VectorType::compMin(loc1.v2,loc2.v2);
287 return result;
288}
289
293template <typename intT>
295{
296 if (loc1.isEmpty()){ return loc2; } else
297 if (loc2.isEmpty()){ return loc1; } else
298 {
299 // Both regions are not empty; determine surrounding box
300 // in all dimensions.
302 VectorType::compMax(loc1.v2,loc2.v2));
303 }
304}
305
306
307// Clamps the position \p pos to the nearest position inside the SubImageBox.
308// If the SubImageBox is empty, then the result vector contains undefined values.
309template <typename intT>
314
315ML_END_NAMESPACE
316
317#endif //of __mlSubImageBox_H
318
319
TSubImageBox< intT > merge(const TSubImageBox< intT > &box) const
Member function version to merge this with a given box.
void translate(const VectorType &offsetVector)
Shifts the entire box by an offset given by offsetVector.
TSubImageBox< intT > intersect(const TSubImageBox< intT > &box) const
Member function version to intersect this with a given box.
static TSubImageBox< intT > intersect(const TSubImageBox< intT > &box1, const TSubImageBox< intT > &box2)
TImageVector< intT > VectorType
The vector type used for corner members v1 and v2.
static void get3DCorners(const TSubImageBox< intT > &box, VectorType corners[8])
bool operator!=(const TSubImageBox< intT > &box) const
Returns false if box has identical components; otherwise, it returns true.
TSubImageBox(const VectorType &vector1, const VectorType &vector2)
bool contains(const VectorType &position) const
Returns true if position is inside the SubImageBox.
VectorType clamp(const VectorType &position) const
bool operator==(const TSubImageBox< intT > &box) const
Returns true if box has identical components; otherwise, it returns false.
static TSubImageBox< intT > merge(const TSubImageBox< intT > &box1, const TSubImageBox< intT > &box2)
intT getNumVoxels() const
TSubImageBox(const VectorType extent)
bool isEmpty() const
VectorType getExtent() const
TVector< TVectorBase > compMin(const TVector< TVectorBase > &b) const
Returns the component-wise minimum of components of this and b.
TVector< TVectorBase > compMax(const TVector< TVectorBase > &b) const
Returns the component-wise maximum of components of this and b.
TSubImageBox< MLint > SubImageBox
Defines the standard SubImageBox type used in the ML. Its size varies with the size of the MLint type...
TImageVector< MLint > ImageVector
Defines the standard ImageVector type that is used by the ML for indexing and coordinates.
STL namespace.
MLEXPORT std::ostream & operator<<(std::ostream &s, const ml::Field &v)
Overloads the operator '<<' for stream output of Field objects.