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 
23 ML_START_NAMESPACE
24 
25 //-------------------------------------------------------------------------
51 //-------------------------------------------------------------------------
52 template<typename intT> class TSubImageBox
53 {
54 
55 public:
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  }
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 
175  void makeEmpty()
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 
235 ML_END_NAMESPACE
236 
237 //-----------------------------------------------------------------------------------
238 // Stream output for std::ostream
239 //-----------------------------------------------------------------------------------
240 namespace 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 
252 ML_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.
263 template <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.
281 template <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 
293 template <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.
301  return TSubImageBox<intT>(VectorType::compMin(loc1.v1,loc2.v1),
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.
309 template <typename intT>
311 {
312  return VectorType::compMax(VectorType::compMin(pos, v2), v1);
313 }
314 
315 ML_END_NAMESPACE
316 
317 #endif //of __mlSubImageBox_H
318 
319 
void set(const ComponentType v=0)
Sets all components to v or - if v is not specified - to 0.
This class defines a rectangular subimage region of standard ML dimensions.
Definition: mlSubImageBox.h:53
TSubImageBox()
Constructor: creates an empty subimage region by setting v1 to (0,...,0) and v2 to (-1,...
Definition: mlSubImageBox.h:77
void makeEmpty()
Makes box empty by setting v1 to (0,...,0) and v2 to (-1,...,-1), i.e., constructor state is restored...
void translate(const VectorType &offsetVector)
Shifts the entire box by an offset given by offsetVector.
VectorType v1
Corner v1 of the subimage region (included in region).
Definition: mlSubImageBox.h:63
static TSubImageBox< intT > intersect(const TSubImageBox< intT > &box1, const TSubImageBox< intT > &box2)
Returns the overlapping region of subimage regions box1 and box2.
TImageVector< intT > VectorType
The vector type used for corner members v1 and v2.
Definition: mlSubImageBox.h:57
static void get3DCorners(const TSubImageBox< intT > &box, VectorType corners[8])
Returns the corners of the 3D box extents of box in corners.
bool operator!=(const TSubImageBox< intT > &box) const
Returns false if box has identical components; otherwise, it returns true.
void correct()
Swaps all components where v1.
TSubImageBox(const VectorType &vector1, const VectorType &vector2)
Constructor: creates a subimage from two passed vectors vector1 and vector2.
Definition: mlSubImageBox.h:84
bool contains(const VectorType &position) const
Returns true if position is inside the SubImageBox.
VectorType v2
Corner v2 of the subimage region (also included in region!).
Definition: mlSubImageBox.h:69
TSubImageBox< intT > intersect(const TSubImageBox< intT > &box) const
Member function version to intersect this with a given box.
VectorType clamp(const VectorType &position) const
Clamps the position to the nearest position inside the SubImageBox.
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)
Returns the region containing both subimage regions box1 and box2.
TSubImageBox< intT > merge(const TSubImageBox< intT > &box) const
Member function version to merge this with a given box.
intT getNumVoxels() const
Returns number of voxels in the subimage region, i.e., the product of all extents if this is not empt...
TSubImageBox(const VectorType extent)
Constructor: creates a subimage from an extent, i.e., v1 is set to (0,...,0) and v2 is set to (extent...
Definition: mlSubImageBox.h:90
bool isEmpty() const
Returns true if subimage region is empty, i.e., if any of the components of v1 is greater than the co...
VectorType getExtent() const
Returns the extents of the subimage region.
MLEXPORT std::ostream & operator<<(std::ostream &s, const ml::Field &v)
Overloads the operator '<<' for stream output of Field objects.
FloatingPointVector< T, size, DataContainer > compMax(FloatingPointVector< T, size, DataContainer > buffer1, const FloatingPointVector< T, size, DataContainer > &buffer2)
Component-wise maximum of buffer1 and buffer2.
FloatingPointVector< T, size, DataContainer > clamp(FloatingPointVector< T, size, DataContainer > vec, const FloatingPointVector< T, size, DataContainer > &lower, const FloatingPointVector< T, size, DataContainer > &upper)
Returns a new vector with all components from vec clamped to range [lower, upper].
T compMul(const FloatingPointVector< T, size, DataContainer > &vec)
Returns the product of all components.
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.
FloatingPointVector< T, size, DataContainer > compMin(FloatingPointVector< T, size, DataContainer > buffer1, const FloatingPointVector< T, size, DataContainer > &buffer2)
Component-wise minimum of buffer1 and buffer2.