aimstil  5.0.5
imageArith.h
Go to the documentation of this file.
1 #ifndef TIL_IMAGEARITH_H
2 #define TIL_IMAGEARITH_H
3 
4 // includes from STL
5 #include <limits>
6 
7 // includes from BOOST
8 #include <boost/type_traits.hpp>
9 
10 // includes from TIL library
11 #include "til/til_common.h"
12 #include "til/imageIterator.h"
13 #include "til/imageTools.h"
14 #include "til/labels.h"
15 
16 // Namespace
17 namespace til {
18 
19 
20 // TODO: remove this: use til::fill instead
21 template < class TImage >
22 void set(TImage &im, typename TImage::value_type value)
23 {
24  typename Iterator<TImage>::Linear iIm(im);
25  for (; !iIm.isAtEnd(); ++iIm)
26  {
27  *iIm = value;
28  }
29 }
30 
31 template < class TImage >
32 void neg(TImage & im)
33 {
34  typename Iterator<TImage>::Linear iIm(im);
35  for (; !iIm.isAtEnd(); ++iIm)
36  {
37  *iIm = -*iIm;
38  }
39 }
40 
41 
48 
49 /*
50 template < class TImage1, class Unknown >
51 void mul(const Ptr<TImage1> &im1, Unknown u)
52 {
53  mul(im1, u, int_to_type< IS_SMARTPTR_TYPE(Unknown) >());
54 }
55 
56 
57 template < class TImage1, class TImage2 >
58 void mul(const Ptr<TImage1> &im1, const ConstPtr<TImage2> &im2, int_to_type<true>)
59 {
60  similarityCheck(im1, im2);
61 
62  typename Iterator<TImage1>::Linear iIm1(im1);
63  typename Iterator<TImage2>::ConstLinear iIm2(im2);
64 
65  for (; !iIm1.isAtEnd(); ++iIm1, ++iIm2)
66  {
67  *iIm1 *= *iIm2;
68  }
69 }
70 
71 template < class TImage, typename TMultiplier >
72 void mul(const Ptr<TImage> &im, TMultiplier constant, int_to_type<false>)
73 {
74  typename Iterator<TImage>::Linear iIm(im);
75  for (; !iIm.isAtEnd(); ++iIm)
76  {
77  *iIm *= constant;
78  }
79 }
80 */
81 
82 // NB: I chose not to ignore warnings here, as this information might still be usefull to
83 // the programmer.
84 //#pragma warning ( push )
85 //#pragma warning ( disable : 4244 ) // conversion from X to Y, possible loss of data
86 
87 namespace detail
88 {
89  template < class TImage1, class TImage2 >
90  void
91  mul_ii(TImage1 &im1, const TImage2 &im2)
92  {
93  similarityCheck(im1, im2);
94 
95  typename Iterator<TImage1>::Linear iIm1(im1);
96  typename Iterator<TImage2>::ConstLinear iIm2(im2);
97 
98  for (; !iIm1.isAtEnd(); ++iIm1, ++iIm2)
99  {
100  *iIm1 *= *iIm2;
101  }
102  }
103 }
104 
109 template < class TImage1, class TImage2 >
110 inline
111 typename enable_if_c<
112  is_Image<TImage1>::value &&
113  is_Image<TImage2>::value
114 >::type
115 mul
116 (
117  TImage1 &im1,
118  const TImage2 &im2
119 )
120 {
121  detail::mul_ii(im1, im2);
122 }
123 
124 
125 namespace detail{
126 
127  template < class TImage, typename TMultiplier >
128  void mul_iv(TImage &im, const TMultiplier & constant)
129  {
130  typename Iterator<TImage>::Linear iIm(im);
131  //int c = 0;
132  for (; !iIm.isAtEnd(); ++iIm)
133  {
134  *iIm *= constant;
135  /*
136  if ((++c % int(im.size()/40.0)) == 0)
137  {
138  std::cout << c << std::flush;
139  if (c > im.size())
140  {
141  std::cout << "weird!!" << std::endl;
142  return;
143  }
144  }
145  */
146  }
147  //std::cout << std::endl;
148  }
149 }
150 
155 template < class TImage, typename TMultiplier >
156 typename disable_if_c<
157  // secong argument should not be an image
158  is_Image<TMultiplier>::value ||
159  // the constant should have the same precision as the image
160  !boost::is_same<typename precision<TImage>::type, typename precision<TMultiplier>::type>::value
161 >::type
162 mul
163 (
164  TImage &im,
165  const TMultiplier & constant
166 )
167 {
168  detail::mul_iv(im, constant);
169 }
170 
171 
172 
173 // AND is a reserved word
174 
175 /*
176 template < class T >
177 void and(Ptr<Image<T> > &im1, Ptr<Image<T> > &im2)
178 {
179 
180  similarityCheck(im1, im2);
181 
182  T *pIm1 = im1->getPointer();
183  const T *pIm2 = im2.getConstPointer();
184 
185  for (int n=0; n<im1->size(); ++n)
186  {
187  if (!(*pIm2)) *pIm1 = 0;
188  ++pIm1;
189  ++pIm2;
190  }
191 }
192 */
193 
194 
195 template < class TImage >
196 void div(TImage & im1, const TImage & im2)
197 {
198  typedef typename TImage::value_type value_type;
199 
200  const value_type EPSILON = 16*std::numeric_limits<value_type>::epsilon();
201 
202  similarityCheck(im1, im2);
203 
204  typename Iterator<TImage>::Linear iIm1(im1);
205  typename Iterator<TImage>::ConstLinear iIm2(im2);
206 
207  for (; !iIm1.isAtEnd(); ++iIm1, ++iIm2);
208  {
209  if (abs(*iIm2) <= EPSILON)
210  {
211  throw std::runtime_error("Division by zero");
212  }
213  *iIm1 /= *iIm2;
214  }
215 }
216 
217 
218 // Deliberately left unimplemented
219 // use mul(im, 1/scalar) instead
220 
221 template < class TImage >
222 void div(TImage &im, typename TImage::value_type scalar);
223 
224 
225 
226 template < class TImage1, class TImage2 >
227 typename enable_if_c<
228  is_Image<TImage1>::value &&
229  is_Image<TImage2>::value
230 >::type
231 sub(TImage1 & im1, const TImage2 & im2)
232 {
233  typedef typename TImage1::value_type TPixel1;
234  typedef typename TImage2::value_type TPixel2;
235 
236  similarityCheck(im1, im2);
237 
238  typename Iterator<TImage1>::Linear iIm1(im1);
239  typename Iterator<TImage2>::ConstLinear iIm2(im2);
240 
241  for (; !iIm1.isAtEnd(); ++iIm1, ++iIm2)
242  {
243  *iIm1 -= castValue<TPixel2, TPixel1>(*iIm2);
244  }
245 }
246 
247 
248 template < class TImage, typename T >
249 typename enable_if_c<
250  is_Image<TImage>::value &&
251  !is_Image<T>::value
252 >::type
253 sub(TImage & im, T scalar)
254 {
255  typename Iterator<TImage>::Linear iIm(im);
256  for (; !iIm.isAtEnd(); ++iIm)
257  {
258  *iIm -= scalar;
259  }
260 }
261 
262 class Add
263 {
264 public:
265  template < typename T1, typename T2 >
266  void operator() (const T1 &a, const T2 &b) const
267  {
268  add(a, b);
269  }
270 };
271 
272 template < class TImage1, class TImage2 >
273 typename enable_if_c<
274  is_Image<TImage1>::value &&
275  is_Image<TImage2>::value
276 >::type
277 add(TImage1 & im1, const TImage2 & im2)
278 {
279  typedef typename TImage1::value_type TPixel1;
280  typedef typename TImage2::value_type TPixel2;
281 
282  similarityCheck(im1, im2);
283 
284  typename Iterator<TImage1>::Linear iIm1(im1);
285  typename Iterator<TImage2>::ConstLinear iIm2(im2);
286 
287  for (; !iIm1.isAtEnd(); ++iIm1, ++iIm2)
288  {
289  *iIm1 += castValue<TPixel2, TPixel1>(*iIm2);
290  }
291 }
292 
293 template < class TImage, typename T >
294 typename enable_if_c<
295  is_Image<TImage>::value &&
296  !is_Image<T>::value
297 >::type
298 add(TImage & im, T scalar)
299 {
300  typename Iterator<TImage>::Linear iIm(im);
301  for (; !iIm.isAtEnd(); ++iIm)
302  {
303  *iIm += scalar;
304  }
305 }
306 
307 
308 
309 template < class TImage >
310 void square(const TImage & in, TImage & out)
311 {
312  similarityCheck(in, out);
313 
314  typename Iterator<TImage>::ConstLinear iIn(in);
315  typename Iterator<TImage>::Linear iOut(out);
316 
317  for (; !iIn.isAtEnd(); ++iIn, ++iOut)
318  {
319  *iOut = square(*iIn);
320  }
321 }
322 
323 
324 
325 template < class TImage >
326 void sqrt(const TImage &in, TImage &out)
327 {
328  similarityCheck(in, out);
329 
330  typename Iterator<TImage>::ConstLinear iIn(in);
331  typename Iterator<TImage>::Linear iOut(out);
332 
333  for (; !iIn.isAtEnd(); ++iIn, ++iOut)
334  {
335  *iOut = sqrt(*iIn);
336  }
337 }
338 
339 namespace functor
340 {
341 
342 } // namespace functor
343 
344 } // namespace til
345 
346 
347 #endif
348 
A trait class to assign iterators to image types.
void mul_ii(TImage1 &im1, const TImage2 &im2)
Definition: imageArith.h:91
Numerical precision of the data for storage classes.
Definition: traits.h:48
TRes div(T1 x, T2 y)
Definition: functors.h:406
void sqrt(const TImage &in, TImage &out)
Definition: imageArith.h:326
void similarityCheck(const TImage1 &im1, const TImage2 &im2)
Check whether both images are allocated and have the same size and voxel size.
Definition: imageTools.h:75
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
TRes sub(T1 x, T2 y)
Definition: functors.h:398
void mul_iv(TImage &im, const TMultiplier &constant)
Definition: imageArith.h:128
General macros, definitions and functions.
Small miscellaneous utility functions for images.
Defines empty classes that serves as labels.
TRes add(T1 x, T2 y)
Definition: functors.h:394
numeric_array< T, D > abs(const numeric_array< T, D > &a)
Absolute value, element-wise.
void neg(TImage &im)
Definition: imageArith.h:32
TRes mul(T1 x, T2 y)
Definition: functors.h:402
void square(const TImage &in, TImage &out)
Definition: imageArith.h:310
Template tool to enable a template specialization under some condition.