SMIL  0.9.1
DImageArith.hpp
1 /*
2  * Copyright (c) 2011-2016, Matthieu FAESSEL and ARMINES
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Matthieu FAESSEL, or ARMINES nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 
30 #ifndef _D_IMAGE_ARITH_HPP
31 #define _D_IMAGE_ARITH_HPP
32 
33 #include <typeinfo>
34 
35 #include "DBaseImageOperations.hpp"
36 #include "DLineArith.hpp"
37 #include "Core/include/DTime.h"
38 #include "Core/include/private/DTraits.hpp"
39 
40 namespace smil
41 {
42 
61  template <class T>
62  RES_T fill(Image<T> &imOut, const T &value)
63  {
64  ASSERT_ALLOCATED(&imOut);
65 
66  return unaryImageFunction<T, fillLine<T> >(imOut, value).retVal;
67  }
68 
77  template <class T>
78  RES_T randFill(Image<T> &imOut)
79  {
80  ASSERT_ALLOCATED(&imOut);
81 
82  typename ImDtTypes<T>::lineType pixels = imOut.getPixels();
83 
84  // Initialize random number generator
85  struct timeval tv;
86  gettimeofday(&tv, 0);
87  srand(tv.tv_usec);
88 
89  double rangeT = ImDtTypes<T>::cardinal();
90  T minT = ImDtTypes<T>::min();
91 
92  for (size_t i=0;i<imOut.getPixelCount();i++)
93  pixels[i] = T( rand()/double(RAND_MAX) * rangeT + double(minT) );
94 
95  imOut.modified();
96 
97  return RES_OK;
98  }
99 
100 
113  template <class T1, class T2>
114  RES_T copy(const Image<T1> &imIn, size_t startX, size_t startY, size_t startZ, size_t sizeX, size_t sizeY, size_t sizeZ, Image<T2> &imOut, size_t outStartX=0, size_t outStartY=0, size_t outStartZ=0)
115  {
116  ASSERT_ALLOCATED(&imIn, &imOut);
117 
118  size_t inW = imIn.getWidth();
119  size_t inH = imIn.getHeight();
120  size_t inD = imIn.getDepth();
121 
122  size_t outW = imOut.getWidth();
123  size_t outH = imOut.getHeight();
124  size_t outD = imOut.getDepth();
125 
126  ASSERT(startX<inW && startY<inH && startZ<inD);
127  ASSERT(outStartX<outW && outStartY<outH && outStartZ<outD);
128 
129  size_t realSx = min( min(sizeX, inW-startX), outW-outStartX );
130  size_t realSy = min( min(sizeY, inH-startY), outH-outStartY );
131  size_t realSz = min( min(sizeZ, inD-startZ), outD-outStartZ );
132 
133  typename Image<T1>::volType slIn = imIn.getSlices() + startZ;
134  typename Image<T2>::volType slOut = imOut.getSlices() + outStartZ;
135 
136  size_t y;
137 
138  for (size_t z=0;z<realSz;z++)
139  {
140  typename Image<T1>::sliceType lnIn = *slIn + startY;
141  typename Image<T2>::sliceType lnOut = *slOut + outStartY;
142 
143 
144  #ifdef USE_OPEN_MP
145  int nthreads = Core::getInstance()->getNumberOfThreads();
146  #pragma omp parallel private(y)
147  #endif // USE_OPEN_MP
148  {
149  #ifdef USE_OPEN_MP
150  #pragma omp for schedule(dynamic,nthreads) nowait
151  #endif // USE_OPEN_MP
152  for (y=0;y<realSy;y++)
153  copyLine<T1,T2>(lnIn[y]+startX, realSx, lnOut[y]+outStartX);
154  }
155 
156  slIn++;
157  slOut++;
158  }
159 
160  imOut.modified();
161  return RES_OK;
162  }
163 
164  // 2D overload
165  template <class T1, class T2>
166  RES_T copy(const Image<T1> &imIn, size_t startX, size_t startY, size_t sizeX, size_t sizeY, Image<T2> &imOut, size_t outStartX=0, size_t outStartY=0, size_t outStartZ=0)
167  {
168  return copy(imIn, startX, startY, 0, sizeX, sizeY, 1, imOut, outStartX, outStartY, outStartZ);
169  }
170 
171  template <class T1, class T2>
172  RES_T copy(const Image<T1> &imIn, size_t startX, size_t startY, size_t startZ, Image<T2> &imOut, size_t outStartX=0, size_t outStartY=0, size_t outStartZ=0)
173  {
174  return copy(imIn, startX, startY, startZ, imIn.getWidth(), imIn.getHeight(), imIn.getDepth(), imOut, outStartX, outStartY, outStartZ);
175  }
176 
177  // 2D overload
178  template <class T1, class T2>
179  RES_T copy(const Image<T1> &imIn, size_t startX, size_t startY, Image<T2> &imOut, size_t outStartX=0, size_t outStartY=0, size_t outStartZ=0)
180  {
181  return copy(imIn, startX, startY, 0, imIn.getWidth(), imIn.getHeight(), 1, imOut, outStartX, outStartY, outStartZ);
182  }
183 
184 
185  template <class T1, class T2>
186  RES_T copy(const Image<T1> &imIn, Image<T2> &imOut, size_t outStartX, size_t outStartY, size_t outStartZ=0)
187  {
188  return copy(imIn, 0, 0, 0, imIn.getWidth(), imIn.getHeight(), imIn.getDepth(), imOut, outStartX, outStartY, outStartZ);
189  }
190 
191 
192  // Copy/cast two images with different types but same size (quick way)
193  template <class T1, class T2>
194  RES_T copy(const Image<T1> &imIn, Image<T2> &imOut)
195  {
196  // Swig is (surprisingly;)) lost with overloads of template functions, so we try to reorient him
197  if (typeid(imIn)==typeid(imOut))
198  return copy(imIn, imOut);
199 
200  ASSERT_ALLOCATED(&imIn, &imOut);
201 
202  if (!haveSameSize(&imIn, &imOut, NULL))
203  return copy<T1,T2>(imIn, 0, 0, 0, imOut, 0, 0, 0);
204 
205  copyLine<T1,T2>(imIn.getPixels(), imIn.getPixelCount(), imOut.getPixels());
206 
207  imOut.modified();
208  return RES_OK;
209  }
210 
211  template <class T>
212  RES_T copy(const Image<T> &imIn, Image<T> &imOut)
213  {
214  ASSERT_ALLOCATED(&imIn, &imOut);
215 
216  imOut.setSize(imIn);
217 
218  return unaryImageFunction<T, fillLine<T> >(imIn, imOut).retVal;
219  }
220 
226  template <class T>
227  RES_T clone(const Image<T> &imIn, Image<T> &imOut)
228  {
229  ASSERT_ALLOCATED(&imIn);
230 
231  ASSERT((imOut.setSize(imIn)==RES_OK));
232  return copy<T>(imIn, imOut);
233  }
234 
239  template <class T1, class T2>
240  RES_T cast(const Image<T1> &imIn, Image<T2> &imOut)
241  {
242  ASSERT_ALLOCATED(&imIn);
243  ASSERT_SAME_SIZE(&imIn, &imOut);
244 
245  T1 floor_t1 = ImDtTypes<T1>::min();
246  T2 floor_t2 = ImDtTypes<T2>::min();
247  double coeff = double(ImDtTypes<T2>::cardinal()) / double(ImDtTypes<T1>::cardinal());
248 
249  typename Image<T1>::lineType pixIn = imIn.getPixels();
250  typename Image<T2>::lineType pixOut = imOut.getPixels();
251 
252  size_t i, nPix = imIn.getPixelCount();
253 
254  #ifdef USE_OPEN_MP
255  int nthreads = Core::getInstance()->getNumberOfThreads();
256  #pragma omp parallel private(i) num_threads(nthreads)
257  #endif // USE_OPEN_MP
258  {
259  #ifdef USE_OPEN_MP
260  #pragma omp for
261  #endif // USE_OPEN_MP
262  for (i=0;i<nPix;i++)
263  pixOut[i] = floor_t2 + T2( coeff * double(pixIn[i]-floor_t1) );
264  }
265 
266  return RES_OK;
267  }
268 
273  template <class MCT1, class T2>
274  RES_T copyChannel(const Image<MCT1> &imIn, const UINT &chanNum, Image<T2> &imOut)
275  {
276  ASSERT(chanNum < MCT1::channelNumber());
277  ASSERT_ALLOCATED(&imIn, &imOut);
278  ASSERT_SAME_SIZE(&imIn, &imOut);
279 
280  typedef typename MCT1::DataType T1;
281  typename Image<T1>::lineType lineIn = imIn.getPixels().arrays[chanNum];
282  typename Image<T2>::lineType lineOut = imOut.getPixels();
283 
284  copyLine<T1,T2>(lineIn, imIn.getPixelCount(), lineOut);
285  imOut.modified();
286  return RES_OK;
287  }
288 
293  template <class T1, class MCT2>
294  RES_T copyToChannel(const Image<T1> &imIn, const UINT &chanNum, Image<MCT2> &imOut)
295  {
296  ASSERT(chanNum < MCT2::channelNumber());
297  ASSERT_ALLOCATED(&imIn, &imOut);
298  ASSERT_SAME_SIZE(&imIn, &imOut);
299 
300  typedef typename MCT2::DataType T2;
301  typename Image<T1>::lineType lineIn = imIn.getPixels();
302  typename Image<T2>::lineType lineOut = imOut.getPixels().arrays[chanNum];
303 
304  copyLine<T1,T2>(lineIn, imIn.getPixelCount(), lineOut);
305  imOut.modified();
306  return RES_OK;
307  }
308 
313  template <class MCT1, class T2>
314  RES_T splitChannels(const Image<MCT1> &imIn, Image<T2> &im3DOut)
315  {
316  ASSERT_ALLOCATED(&imIn);
317 
318  UINT width = imIn.getWidth(), height = imIn.getHeight();
319  UINT chanNum = MCT1::channelNumber();
320  UINT pixCount = width*height;
321  ASSERT(im3DOut.setSize(width, height, chanNum)==RES_OK);
322 
323  typedef typename MCT1::DataType T1;
324  typename Image<MCT1>::lineType lineIn = imIn.getPixels();
325  typename Image<T2>::lineType lineOut = im3DOut.getPixels();
326 
327  for (UINT i=0;i<chanNum;i++)
328  {
329  copyLine<T1,T2>(lineIn.arrays[i], pixCount, lineOut);
330  lineOut += pixCount;
331  }
332  im3DOut.modified();
333 
334  return RES_OK;
335  }
336 
341  template <class T1, class MCT2>
342  RES_T mergeChannels(const Image<T1> &imIn, Image<MCT2> &imOut)
343  {
344  ASSERT_ALLOCATED(&imIn);
345  UINT chanNum = MCT2::channelNumber();
346  ASSERT(imIn.getDepth()==chanNum);
347 
348  UINT width = imIn.getWidth(), height = imIn.getHeight();
349  UINT pixCount = width*height;
350  imOut.setSize(width, height);
351 
352  typedef typename MCT2::DataType T2;
353  typename Image<T1>::lineType lineIn = imIn.getPixels();
354  typename Image<MCT2>::lineType lineOut = imOut.getPixels();
355 
356  for (UINT i=0;i<chanNum;i++)
357  {
358  copyLine<T1,T2>(lineIn, pixCount, lineOut.arrays[i]);
359  lineIn += pixCount;
360  }
361  imOut.modified();
362 
363  return RES_OK;
364  }
365 
374  template <class T>
375  RES_T inv(const Image<T> &imIn, Image<T> &imOut)
376  {
377  ASSERT_ALLOCATED(&imIn, &imOut);
378  ASSERT_SAME_SIZE(&imIn, &imOut);
379 
380  return unaryImageFunction<T, invLine<T> >(imIn, imOut).retVal;
381  }
382 
392  template <class T>
393  RES_T add(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
394  {
395  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
396  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
397 
398  return binaryImageFunction<T, addLine<T> >(imIn1, imIn2, imOut);
399  }
400 
401  template <class T>
402  RES_T add(const Image<T> &imIn1, const T &value, Image<T> &imOut)
403  {
404  ASSERT_ALLOCATED(&imIn1, &imOut);
405  ASSERT_SAME_SIZE(&imIn1, &imOut);
406 
407  return binaryImageFunction<T, addLine<T> >(imIn1, value, imOut);
408  }
409 
418  template <class T>
419  RES_T addNoSat(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
420  {
421  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
422  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
423 
424  return binaryImageFunction<T, addNoSatLine<T> >(imIn1, imIn2, imOut);
425  }
426 
427  template <class T>
428  RES_T addNoSat(const Image<T> &imIn1, const T &value, Image<T> &imOut)
429  {
430  ASSERT_ALLOCATED(&imIn1, &imOut);
431  ASSERT_SAME_SIZE(&imIn1, &imOut);
432 
433  return binaryImageFunction<T, addNoSatLine<T> >(imIn1, value, imOut);
434  }
435 
436 
445  template <class T>
446  RES_T sub(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
447  {
448  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
449  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
450 
451  return binaryImageFunction<T, subLine<T> >(imIn1, imIn2, imOut);
452  }
453 
454  template <class T>
455  RES_T sub(const Image<T> &imIn1, const T &value, Image<T> &imOut)
456  {
457  return binaryImageFunction<T, subLine<T> >(imIn1, value, imOut);
458  }
459 
460  template <class T>
461  RES_T sub(const T &value, const Image<T> &imIn, Image<T> &imOut)
462  {
463  return binaryImageFunction<T, subLine<T> >(value, imIn, imOut);
464  }
465 
474  template <class T>
475  RES_T subNoSat(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
476  {
477  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
478  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
479 
480  return binaryImageFunction<T, subNoSatLine<T> >(imIn1, imIn2, imOut);
481  }
482 
483  template <class T>
484  RES_T subNoSat(const Image<T> &imIn1, const T &value, Image<T> &imOut)
485  {
486  ASSERT_ALLOCATED(&imIn1, &imOut);
487  ASSERT_SAME_SIZE(&imIn1, &imOut);
488 
489  return binaryImageFunction<T, subNoSatLine<T> >(imIn1, value, imOut);
490  }
491 
492  template <class T>
493  RES_T subNoSat(const T &value, const Image<T> &imIn, Image<T> &imOut)
494  {
495  ASSERT_ALLOCATED(&imIn, &imOut);
496  ASSERT_SAME_SIZE(&imIn, &imOut);
497 
498  return binaryImageFunction<T, subNoSatLine<T> >(value, imIn, imOut);
499  }
500 
504  template <class T>
505  RES_T sup(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
506  {
507  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
508  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
509 
510  return binaryImageFunction<T, supLine<T> >(imIn1, imIn2, imOut);
511  }
512 
513  template <class T>
514  ResImage<T> sup(const Image<T> &imIn1, const Image<T> &imIn2)
515  {
516  ResImage<T> newIm(imIn1);
517 
518  ASSERT(CHECK_ALLOCATED(&imIn1, &imIn2), newIm);
519  ASSERT(CHECK_SAME_SIZE(&imIn1, &imIn2), newIm);
520 
521  sup(imIn1, imIn2, newIm);
522  return newIm;
523  }
524 
525  template <class T>
526  RES_T sup(const Image<T> &imIn1, const T &value, Image<T> &imOut)
527  {
528  ASSERT_ALLOCATED(&imIn1, &imOut);
529  ASSERT_SAME_SIZE(&imIn1, &imOut);
530 
531  return binaryImageFunction<T, supLine<T> >(imIn1, value, imOut);
532  }
533 
537  template <class T>
538  RES_T inf(const Image<T> &imIn1, const T &value, Image<T> &imOut)
539  {
540  ASSERT_ALLOCATED(&imIn1, &imOut);
541  ASSERT_SAME_SIZE(&imIn1, &imOut);
542 
543  return binaryImageFunction<T, infLine<T> >(imIn1, value, imOut);
544  }
545 
546  template <class T>
547  ResImage<T> inf(const Image<T> &imIn1, const Image<T> &imIn2)
548  {
549  ResImage<T> newIm(imIn1);
550 
551  ASSERT(CHECK_ALLOCATED(&imIn1, &imIn2), newIm);
552  ASSERT(CHECK_SAME_SIZE(&imIn1, &imIn2), newIm);
553 
554  inf(imIn1, imIn2, newIm);
555  return newIm;
556  }
557 
558  template <class T>
559  RES_T inf(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
560  {
561  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
562  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
563 
564  return binaryImageFunction<T, infLine<T> >(imIn1, imIn2, imOut);
565  }
566 
571  template <class T>
572  RES_T equ(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
573  {
574  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
575  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
576 
577  return binaryImageFunction<T, equLine<T> >(imIn1, imIn2, imOut);
578  }
579 
580  template <class T>
581  RES_T equ(const Image<T> &imIn, const T &value, Image<T> &imOut)
582  {
583  ASSERT_ALLOCATED(&imIn, &imOut);
584  ASSERT_SAME_SIZE(&imIn, &imOut);
585 
586  return binaryImageFunction<T, equLine<T> >(imIn, value, imOut);
587  }
588 
593  template <class T>
594  bool equ(const Image<T> &imIn1, const Image<T> &imIn2)
595  {
596  ASSERT(CHECK_ALLOCATED(&imIn1, &imIn2), false);
597  ASSERT(CHECK_SAME_SIZE(&imIn1, &imIn2), false);
598 
599  typedef typename Image<T>::lineType lineType;
600  lineType pix1 = imIn1.getPixels();
601  lineType pix2 = imIn2.getPixels();
602 
603  for (size_t i=0;i<imIn1.getPixelCount();i++)
604  if (pix1[i]!=pix2[i])
605  return false;
606 
607  return true;
608  }
609 
614  template <class T>
615  RES_T diff(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
616  {
617  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
618  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
619 
620  return binaryImageFunction<T, diffLine<T> >(imIn1, imIn2, imOut);
621  }
622 
623  template <class T>
624  RES_T diff(const Image<T> &imIn, const T &value, Image<T> &imOut)
625  {
626  ASSERT_ALLOCATED(&imIn, &imOut);
627  ASSERT_SAME_SIZE(&imIn, &imOut);
628 
629  return binaryImageFunction<T, diffLine<T> >(imIn, value, imOut);
630  }
631 
637  template <class T>
638  RES_T absDiff(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
639  {
640  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
641  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
642 
643  return binaryImageFunction<T, absDiffLine<T> >(imIn1, imIn2, imOut);
644  }
645 
649  template <class T>
650  RES_T grt(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
651  {
652  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
653  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
654 
655  return binaryImageFunction<T, grtLine<T> >(imIn1, imIn2, imOut);
656  }
657 
658  template <class T>
659  RES_T grt(const Image<T> &imIn1, const T &value, Image<T> &imOut)
660  {
661  ASSERT_ALLOCATED(&imIn1, &imOut);
662  ASSERT_SAME_SIZE(&imIn1, &imOut);
663 
664  return binaryImageFunction<T, grtLine<T> >(imIn1, value, imOut);
665  }
666 
670  template <class T>
671  RES_T grtOrEqu(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
672  {
673  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
674  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
675 
676  return binaryImageFunction<T, grtOrEquLine<T> >(imIn1, imIn2, imOut);
677  }
678 
679  template <class T>
680  RES_T grtOrEqu(const Image<T> &imIn1, const T &value, Image<T> &imOut)
681  {
682  ASSERT_ALLOCATED(&imIn1, &imOut);
683  ASSERT_SAME_SIZE(&imIn1, &imOut);
684 
685  return binaryImageFunction<T, grtOrEquLine<T> >(imIn1, value, imOut);
686  }
687 
691  template <class T>
692  RES_T low(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
693  {
694  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
695  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
696 
697  return binaryImageFunction<T, lowLine<T> >(imIn1, imIn2, imOut);
698  }
699 
700  template <class T>
701  RES_T low(const Image<T> &imIn1, const T &value, Image<T> &imOut)
702  {
703  ASSERT_ALLOCATED(&imIn1, &imOut);
704  ASSERT_SAME_SIZE(&imIn1, &imOut);
705 
706  return binaryImageFunction<T, lowLine<T> >(imIn1, value, imOut);
707  }
708 
712  template <class T>
713  RES_T lowOrEqu(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
714  {
715  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
716  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
717 
718  return binaryImageFunction<T, lowOrEquLine<T> >(imIn1, imIn2, imOut);
719  }
720 
721  template <class T>
722  RES_T lowOrEqu(const Image<T> &imIn1, const T &value, Image<T> &imOut)
723  {
724  ASSERT_ALLOCATED(&imIn1, &imOut);
725  ASSERT_SAME_SIZE(&imIn1, &imOut);
726 
727  return binaryImageFunction<T, lowOrEquLine<T> >(imIn1, value, imOut);
728  }
729 
733  template <class T>
734  RES_T div(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
735  {
736  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
737  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
738 
739  return binaryImageFunction<T, divLine<T> >(imIn1, imIn2, imOut);
740  }
741 
742 // template <class T>
743 // RES_T div(const Image<T> &imIn, const T &value, Image<T> &imOut)
744 // {
745 // ASSERT_ALLOCATED(&imIn, &imOut);
746 // ASSERT_SAME_SIZE(&imIn, &imOut);
747 //
748 // return binaryImageFunction<T, divLine<T> >(imIn, value, imOut);
749 // }
750 
751  template <class T>
752  RES_T div(const Image<T> &imIn, const double &dValue, Image<T> &imOut)
753  {
754  ASSERT_ALLOCATED(&imIn, &imOut);
755  ASSERT_SAME_SIZE(&imIn, &imOut);
756 
757  typename ImDtTypes<T>::lineType pixIn = imIn.getPixels();
758  typename ImDtTypes<T>::lineType pixOut = imOut.getPixels();
759 
760  for (size_t i=0;i<imIn.getPixelCount();i++)
761  pixOut[i] = pixIn[i] / dValue;
762 
763  return RES_OK;
764  }
765 
769  template <class T>
770  RES_T mul(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
771  {
772  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
773  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
774 
775  return binaryImageFunction<T, mulLine<T> >(imIn1, imIn2, imOut);
776  }
777 
778 // template <class T>
779 // RES_T mul(const Image<T> &imIn1, const T &value, Image<T> &imOut)
780 // {
781 // ASSERT_ALLOCATED(&imIn1, &imOut);
782 // ASSERT_SAME_SIZE(&imIn1, &imOut);
783 //
784 // return binaryImageFunction<T, mulLine<T> >(imIn1, value, imOut);
785 // }
786  template <class T>
787  RES_T mul(const Image<T> &imIn, const double &dValue, Image<T> &imOut)
788  {
789  ASSERT_ALLOCATED(&imIn, &imOut);
790  ASSERT_SAME_SIZE(&imIn, &imOut);
791 
792  typename ImDtTypes<T>::lineType pixIn = imIn.getPixels();
793  typename ImDtTypes<T>::lineType pixOut = imOut.getPixels();
794  double newVal;
795 
796  for (size_t i=0;i<imIn.getPixelCount();i++)
797  {
798  newVal = pixIn[i] * dValue;
799  pixOut[i] = newVal>double(ImDtTypes<T>::max()) ? ImDtTypes<T>::max() : T(newVal);
800  }
801 
802  return RES_OK;
803  }
804 
805 
809  template <class T>
810  RES_T mulNoSat(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
811  {
812  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
813  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
814 
815  return binaryImageFunction<T, mulLine<T> >(imIn1, imIn2, imOut);
816  }
817 
818  template <class T>
819  RES_T mulNoSat(const Image<T> &imIn1, const T &value, Image<T> &imOut)
820  {
821  ASSERT_ALLOCATED(&imIn1, &imOut);
822  ASSERT_SAME_SIZE(&imIn1, &imOut);
823 
824  return binaryImageFunction<T, mulLine<T> >(imIn1, value, imOut);
825  }
826 
832  template <class T>
833  RES_T log(const Image<T> &imIn, Image<T> &imOut, int base=0)
834  {
835  ASSERT_ALLOCATED(&imIn);
836  ASSERT_SAME_SIZE(&imIn, &imOut);
837 
839  func.lineFunction.base = base;
840  return func(imIn, imOut);
841  }
842 
846  template <class T>
847  RES_T logicAnd(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
848  {
849  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
850  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
851 
852  return binaryImageFunction<T, logicAndLine<T> >(imIn1, imIn2, imOut);
853  }
854 
855  template <class T>
856  RES_T bitAnd(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
857  {
858  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
859  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
860 
861  return binaryImageFunction<T, bitAndLine<T> >(imIn1, imIn2, imOut);
862  }
863 
867  template <class T>
868  RES_T logicOr(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
869  {
870  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
871  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
872 
873  return binaryImageFunction<T, logicOrLine<T> >(imIn1, imIn2, imOut);
874  }
875 
876  template <class T>
877  RES_T bitOr(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
878  {
879  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
880  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
881 
882  return binaryImageFunction<T, bitOrLine<T> >(imIn1, imIn2, imOut);
883  }
884 
888  template <class T>
889  RES_T logicXOr(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
890  {
891  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
892  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
893 
894  return binaryImageFunction<T, logicXOrLine<T> >(imIn1, imIn2, imOut);
895  }
896 
897  template <class T>
898  RES_T bitXOr(const Image<T> &imIn1, const Image<T> &imIn2, Image<T> &imOut)
899  {
900  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
901  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
902 
903  return binaryImageFunction<T, bitXOrLine<T> >(imIn1, imIn2, imOut);
904  }
905 
919  template <class T1, class T2>
920  RES_T test(const Image<T1> &imIn1, const Image<T2> &imIn2, const Image<T2> &imIn3, Image<T2> &imOut)
921  {
922  ASSERT_ALLOCATED(&imIn1, &imIn2, &imIn3, &imOut);
923  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imIn3, &imOut);
924 
925  return tertiaryImageFunction<T1, testLine<T1, T2> >(imIn1, imIn2, imIn3, imOut);
926  }
927 
928  template <class T1, class T2>
929  RES_T test(const Image<T1> &imIn1, const Image<T2> &imIn2, const T2 &value, Image<T2> &imOut)
930  {
931  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
932  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
933 
934  return tertiaryImageFunction<T1, testLine<T1, T2> >(imIn1, imIn2, value, imOut);
935  }
936 
937  template <class T1, class T2>
938  RES_T test(const Image<T1> &imIn1, const T2 &value, const Image<T2> &imIn2, Image<T2> &imOut)
939  {
940  ASSERT_ALLOCATED(&imIn1, &imIn2, &imOut);
941  ASSERT_SAME_SIZE(&imIn1, &imIn2, &imOut);
942 
943  return tertiaryImageFunction<T1, testLine<T1, T2> >(imIn1, value, imIn2, imOut);
944  }
945 
946  template <class T1, class T2>
947  RES_T test(const Image<T1> &imIn, const T2 &value1, const T2 &value2, Image<T2> &imOut)
948  {
949  ASSERT_ALLOCATED(&imIn, &imOut);
950  ASSERT_SAME_SIZE(&imIn, &imOut);
951 
952  return tertiaryImageFunction<T1, testLine<T1, T2> >(imIn, value1, value2, imOut);
953  }
954 
955  template <class T1, class imOrValT, class trueT, class falseT, class T2>
956  RES_T _compare_base(const Image<T1> &imIn, const char* compareType, const imOrValT &imOrVal, const trueT &trueImOrVal, const falseT &falseImOrVal, Image<T2> &imOut)
957  {
958  ImageFreezer freeze(imOut);
959 
960  Image<T1> tmpIm(imIn);
961 
962  if (strcmp(compareType, "==")==0)
963  {
964  ASSERT(equ(imIn, imOrVal, tmpIm)==RES_OK);
965  }
966  else if (strcmp(compareType, "!=")==0)
967  {
968  ASSERT(diff(imIn, imOrVal, tmpIm)==RES_OK);
969  }
970  else if (strcmp(compareType, ">")==0)
971  {
972  ASSERT(grt(imIn, imOrVal, tmpIm)==RES_OK);
973  }
974  else if (strcmp(compareType, "<")==0)
975  {
976  ASSERT(low(imIn, imOrVal, tmpIm)==RES_OK);
977  }
978  else if (strcmp(compareType, ">=")==0)
979  {
980  ASSERT(grtOrEqu(imIn, imOrVal, tmpIm)==RES_OK);
981  }
982  else if (strcmp(compareType, "<=")==0)
983  {
984  ASSERT(lowOrEqu(imIn, imOrVal, tmpIm)==RES_OK);
985  }
986  else
987  {
988  ERR_MSG("Unknown operation");
989  return RES_ERR;
990  }
991 
992  ASSERT(test(tmpIm, trueImOrVal, falseImOrVal, imOut)==RES_OK);
993 
994  return RES_OK;
995 
996  }
997 
1002  template <class T1, class T2>
1003  RES_T compare(const Image<T1> &imIn1, const char* compareType, const Image<T1> &imIn2, const Image<T2> &trueIm, const Image<T2> &falseIm, Image<T2> &imOut)
1004  {
1005  return _compare_base<T1, Image<T1>, Image<T2>, Image<T2>, T2 >(imIn1, compareType, imIn2, trueIm, falseIm, imOut);
1006  }
1007 
1008  template <class T1, class T2>
1009  RES_T compare(const Image<T1> &imIn1, const char* compareType, const Image<T1> &imIn2, const T2 &trueVal, const Image<T2> &falseIm, Image<T2> &imOut)
1010  {
1011  return _compare_base<T1, Image<T1>, T2, Image<T2>, T2 >(imIn1, compareType, imIn2, trueVal, falseIm, imOut);
1012  }
1013 
1014  template <class T1, class T2>
1015  RES_T compare(const Image<T1> &imIn1, const char* compareType, const Image<T1> &imIn2, const Image<T2> &trueIm, const T2 &falseVal, Image<T2> &imOut)
1016  {
1017  return _compare_base<T1, Image<T1>, Image<T2>, T2, T2>(imIn1, compareType, imIn2, trueIm, falseVal, imOut);
1018  }
1019 
1020  template <class T1, class T2>
1021  RES_T compare(const Image<T1> &imIn1, const char* compareType, const Image<T1> &imIn2, const T2 &trueVal, const T2 &falseVal, Image<T2> &imOut)
1022  {
1023  return _compare_base<T1, Image<T1>, T2, T2, T2 >(imIn1, compareType, imIn2, trueVal, falseVal, imOut);
1024  }
1025 
1026 
1027  template <class T1, class T2>
1028  RES_T compare(const Image<T1> &imIn, const char* compareType, const T1 &value, const Image<T2> &trueIm, const Image<T2> &falseIm, Image<T2> &imOut)
1029  {
1030  return _compare_base<T1, T1, Image<T2>, Image<T2>, T2 >(imIn, compareType, value, trueIm, falseIm, imOut);
1031  }
1032 
1033  template <class T1, class T2>
1034  RES_T compare(const Image<T1> &imIn, const char* compareType, const T1 &value, const T2 &trueVal, const Image<T2> &falseIm, Image<T2> &imOut)
1035  {
1036  return _compare_base<T1, T1, T2, Image<T2>, T2 >(imIn, compareType, value, trueVal, falseIm, imOut);
1037  }
1038 
1039  template <class T1, class T2>
1040  RES_T compare(const Image<T1> &imIn, const char* compareType, const T1 &value, const Image<T2> &trueIm, const T2 &falseVal, Image<T2> &imOut)
1041  {
1042  return _compare_base<T1, T1, Image<T2>, T2, T2 >(imIn, compareType, value, trueIm, falseVal, imOut);
1043  }
1044 
1045  template <class T1, class T2>
1046  RES_T compare(const Image<T1> &imIn, const char* compareType, const T1 &value, const T2 &trueVal, const T2 &falseVal, Image<T2> &imOut)
1047  {
1048  return _compare_base<T1, T1, T2, T2, T2 >(imIn, compareType, value, trueVal, falseVal, imOut);
1049  }
1050 
1051 
1059  template <class T>
1060  RES_T mask(const Image<T> &imIn, const Image<T> &imMask, Image<T> &imOut)
1061  {
1062  return test<T>(imMask, imIn, T(0), imOut);
1063  }
1064 
1065 
1091  template <class T1, class mapT, class T2>
1092  RES_T applyLookup(const Image<T1> &imIn, const mapT &_map, Image<T2> &imOut, T2 defaultValue=T2(0))
1093  {
1094  ASSERT(!_map.empty(), "Input map is empty", RES_ERR);
1095  ASSERT_ALLOCATED(&imIn, &imOut);
1096  ASSERT_SAME_SIZE(&imIn, &imOut);
1097 
1098  // Verify that the max(measure) doesn't exceed the T2 type max
1099  typename mapT::const_iterator max_it = std::max_element(_map.begin(), _map.end(), map_comp_value_less());
1100  ASSERT(( max_it->second <= ImDtTypes<T2>::max() ), "Input map max exceeds data type max!", RES_ERR);
1101 
1102 
1103  typename Image<T1>::lineType pixIn = imIn.getPixels();
1104  typename Image<T2>::lineType pixOut = imOut.getPixels();
1105 
1106  typename mapT::const_iterator it;
1107 
1108  for (size_t i=0;i<imIn.getPixelCount();i++)
1109  {
1110  it = _map.find(*pixIn);
1111  if (it!=_map.end())
1112  *pixOut = T2(it->second);
1113  else
1114  *pixOut = defaultValue;
1115  pixIn++;
1116  pixOut++;
1117  }
1118  imOut.modified();
1119 
1120  return RES_OK;
1121  }
1122 
1123 
1124 #ifndef SWIG
1125  template <class T1, class T2>
1126  ENABLE_IF( !IS_SAME(T1,UINT8) && !IS_SAME(T1,UINT16), RES_T ) // SFINAE General case
1127  applyLookup(const Image<T1> &imIn, const map<T1,T2> &lut, Image<T2> &imOut, T2 defaultValue=T2(0))
1128  {
1129  return applyLookup<T1, map<T1,T2>, T2>(imIn, lut, imOut, defaultValue);
1130  }
1131 
1132  // Specialization for T1==UINT8 or T1==UINT16
1133  template <class T1, class T2>
1134  ENABLE_IF( IS_SAME(T1,UINT8) || IS_SAME(T1,UINT16), RES_T ) // SFINAE For T1==UINT8 || T1==UINT16
1135  applyLookup(const Image<T1> &imIn, const map<T1,T2> &lut, Image<T2> &imOut, T2 defaultValue=T2(0))
1136  {
1137  ASSERT(!lut.empty(), "Input map is empty", RES_ERR);
1138  ASSERT_ALLOCATED(&imIn, &imOut);
1139  ASSERT_SAME_SIZE(&imIn, &imOut);
1140 
1142 
1143  for (int i=0;i<ImDtTypes<T1>::max();i++)
1144  outVals[i] = defaultValue;
1145 
1146  typename Image<T1>::lineType pixIn = imIn.getPixels();
1147  typename Image<T2>::lineType pixOut = imOut.getPixels();
1148 
1149  for (typename map<T1,T2>::const_iterator it = lut.begin(); it!=lut.end(); it++)
1150  outVals[it->first] = it->second;
1151 
1152  for (size_t i=0;i<imIn.getPixelCount();i++)
1153  pixOut[i] = outVals[ pixIn[i] ];
1154 
1155  imOut.modified();
1156 
1157  ImDtTypes<T2>::deleteLine(outVals);
1158 
1159  return RES_OK;
1160  }
1161 #else // SWIG
1162  template <class T1, class T2>
1163  RES_T applyLookup(const Image<T1> &imIn, const map<T1,T2> &lut, Image<T2> &imOut, T2 defaultValue=T2(0));
1164 #endif // SWIG
1165 
1166 
1167 
1170 } // namespace smil
1171 
1172 
1173 
1174 #endif // _D_IMAGE_ARITH_HPP
1175 
RES_T absDiff(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Absolute difference ("vertical distance") between two images.
Definition: DImageArith.hpp:638
Definition: DColorConvert.h:38
RES_T sub(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Subtraction.
Definition: DImageArith.hpp:446
RES_T grt(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Greater operator.
Definition: DImageArith.hpp:650
RES_T copy(const Image< T1 > &imIn, size_t startX, size_t startY, size_t startZ, size_t sizeX, size_t sizeY, size_t sizeZ, Image< T2 > &imOut, size_t outStartX=0, size_t outStartY=0, size_t outStartZ=0)
Copy image.
Definition: DImageArith.hpp:114
Definition: DBaseImage.h:235
RES_T logicOr(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Logic OR operator.
Definition: DImageArith.hpp:868
Definition: DCommon.h:93
RES_T copyToChannel(const Image< T1 > &imIn, const UINT &chanNum, Image< MCT2 > &imOut)
Copy a single channel image into a channel of multichannel image.
Definition: DImageArith.hpp:294
Definition: DImage.hpp:50
Definition: DBaseImageOperations.hpp:72
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:110
RES_T inv(const Image< T > &imIn, Image< T > &imOut)
Invert an image.
Definition: DImageArith.hpp:375
virtual RES_T setSize(size_t w, size_t h, size_t d=1, bool doAllocate=true)
Set the size of image.
Definition: DImage.hxx:319
RES_T fill(Image< T > &imOut, const T &value)
Fill an image with a given value.
Definition: DImageArith.hpp:62
RES_T sup(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Sup of two images.
Definition: DImageArith.hpp:505
RES_T log(const Image< T > &imIn, Image< T > &imOut, int base=0)
Logarithm.
Definition: DImageArith.hpp:833
RES_T add(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Addition.
Definition: DImageArith.hpp:393
RES_T mulNoSat(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Multiply (without type max check)
Definition: DImageArith.hpp:810
RES_T mergeChannels(const Image< T1 > &imIn, Image< MCT2 > &imOut)
Merge slices of a 3D image into a multichannel image.
Definition: DImageArith.hpp:342
size_t getHeight() const
Get image height.
Definition: DBaseImage.h:91
RES_T low(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Lower operator.
Definition: DImageArith.hpp:692
bool equ(const Image< T > &imIn1, const Image< T > &imIn2)
Test equality between two images.
Definition: DImageArith.hpp:594
virtual void modified()
Trigger modified event (allows to force display update)
Definition: DImage.hxx:223
RES_T randFill(Image< T > &imOut)
Fill an image with random values.
Definition: DImageArith.hpp:78
size_t getWidth() const
Get image width.
Definition: DBaseImage.h:87
RES_T addNoSat(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Addition (without saturation check)
Definition: DImageArith.hpp:419
RES_T lowOrEqu(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Lower or equal operator.
Definition: DImageArith.hpp:713
RES_T grtOrEqu(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Greater or equal operator.
Definition: DImageArith.hpp:671
size_t getPixelCount() const
Get the number of pixels.
Definition: DBaseImage.h:150
RES_T copyChannel(const Image< MCT1 > &imIn, const UINT &chanNum, Image< T2 > &imOut)
Copy a channel of multichannel image into a single channel image.
Definition: DImageArith.hpp:274
RES_T logicAnd(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Logic AND operator.
Definition: DImageArith.hpp:847
RES_T cast(const Image< T1 > &imIn, Image< T2 > &imOut)
Cast from an image type to another.
Definition: DImageArith.hpp:240
Definition: DBaseImageOperations.hpp:114
RES_T compare(const Image< T1 > &imIn1, const char *compareType, const Image< T1 > &imIn2, const Image< T2 > &trueIm, const Image< T2 > &falseIm, Image< T2 > &imOut)
Compare two images (or an image and a value)
Definition: DImageArith.hpp:1003
Definition: DTypes.hpp:78
RES_T mask(const Image< T > &imIn, const Image< T > &imMask, Image< T > &imOut)
Image mask.
Definition: DImageArith.hpp:1060
Main Image class.
Definition: DQVtkViewer.hpp:44
RES_T inf(const Image< T > &imIn1, const T &value, Image< T > &imOut)
Inf of two images.
Definition: DImageArith.hpp:538
RES_T mul(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Multiply.
Definition: DImageArith.hpp:770
RES_T applyLookup(const Image< T1 > &imIn, const mapT &_map, Image< T2 > &imOut, T2 defaultValue=T2(0))
Apply a lookup map.
Definition: DImageArith.hpp:1092
RES_T logicXOr(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Logic XOR operator.
Definition: DImageArith.hpp:889
Definition: DBaseImageOperations.hpp:161
RES_T splitChannels(const Image< MCT1 > &imIn, Image< T2 > &im3DOut)
Split channels of multichannel image to a 3D image with each channel on a Z slice.
Definition: DImageArith.hpp:314
RES_T clone(const Image< T > &imIn, Image< T > &imOut)
Clone an image.
Definition: DImageArith.hpp:227
volType getSlices() const
Get an array containing the start offset of each slice.
Definition: DImage.hpp:118
RES_T test(const Image< T1 > &imIn1, const Image< T2 > &imIn2, const Image< T2 > &imIn3, Image< T2 > &imOut)
Test.
Definition: DImageArith.hpp:920
size_t getDepth() const
Get image depth (Z)
Definition: DBaseImage.h:95
RES_T subNoSat(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Subtraction (without type minimum check)
Definition: DImageArith.hpp:475
RES_T diff(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Difference between two images.
Definition: DImageArith.hpp:615
RES_T div(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Division.
Definition: DImageArith.hpp:734