37 #ifndef VIGRA_TRANSFORMIMAGE_HXX
38 #define VIGRA_TRANSFORMIMAGE_HXX
40 #include "utilities.hxx"
41 #include "numerictraits.hxx"
42 #include "iteratortraits.hxx"
43 #include "rgbvalue.hxx"
44 #include "functortraits.hxx"
60 template <
class SrcIterator,
class SrcAccessor,
61 class DestIterator,
class DestAccessor,
class Functor>
63 transformLine(SrcIterator s,
64 SrcIterator send, SrcAccessor src,
65 DestIterator d, DestAccessor dest,
68 for(; s != send; ++s, ++d)
69 dest.set(f(src(s)), d);
72 template <
class SrcIterator,
class SrcAccessor,
73 class MaskIterator,
class MaskAccessor,
74 class DestIterator,
class DestAccessor,
77 transformLineIf(SrcIterator s,
78 SrcIterator send, SrcAccessor src,
79 MaskIterator m, MaskAccessor mask,
80 DestIterator d, DestAccessor dest,
83 for(; s != send; ++s, ++d, ++m)
85 dest.set(f(src(s)), d);
166 template <
class SrcImageIterator,
class SrcAccessor,
167 class DestImageIterator,
class DestAccessor,
class Functor>
170 SrcImageIterator src_lowerright, SrcAccessor sa,
171 DestImageIterator dest_upperleft, DestAccessor da,
174 int w = src_lowerright.x - src_upperleft.x;
176 for(; src_upperleft.y < src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y)
178 transformLine(src_upperleft.rowIterator(),
179 src_upperleft.rowIterator() + w, sa,
180 dest_upperleft.rowIterator(), da, f);
184 template <
class SrcImageIterator,
class SrcAccessor,
185 class DestImageIterator,
class DestAccessor,
class Functor>
188 transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
189 pair<DestImageIterator, DestAccessor> dest,
193 dest.first, dest.second, f);
286 template <
class SrcImageIterator,
class SrcAccessor,
287 class MaskImageIterator,
class MaskAccessor,
288 class DestImageIterator,
class DestAccessor,
292 SrcImageIterator src_lowerright, SrcAccessor sa,
293 MaskImageIterator mask_upperleft, MaskAccessor ma,
294 DestImageIterator dest_upperleft, DestAccessor da,
297 int w = src_lowerright.x - src_upperleft.x;
299 for(; src_upperleft.y < src_lowerright.y;
300 ++src_upperleft.y, ++mask_upperleft.y, ++dest_upperleft.y)
302 transformLineIf(src_upperleft.rowIterator(),
303 src_upperleft.rowIterator() + w, sa,
304 mask_upperleft.rowIterator(), ma,
305 dest_upperleft.rowIterator(), da, f);
309 template <
class SrcImageIterator,
class SrcAccessor,
310 class MaskImageIterator,
class MaskAccessor,
311 class DestImageIterator,
class DestAccessor,
315 transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
316 pair<MaskImageIterator, MaskAccessor> mask,
317 pair<DestImageIterator, DestAccessor> dest,
321 mask.first, mask.second,
322 dest.first, dest.second, f);
403 template <
class SrcImageIterator,
class SrcAccessor,
404 class DestImageIterator,
class DestAccessor,
class Functor>
407 DestImageIterator destul, DestAccessor da, Functor
const & grad)
409 int w = srclr.x - srcul.x;
410 int h = srclr.y - srcul.y;
413 SrcImageIterator sy = srcul;
414 DestImageIterator dy = destul;
416 static const Diff2D left(-1,0);
417 static const Diff2D right(1,0);
418 static const Diff2D top(0,-1);
419 static const Diff2D bottom(0,1);
421 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
422 TmpType diffx, diffy;
424 SrcImageIterator sx = sy;
425 DestImageIterator dx = dy;
427 diffx = sa(sx) - sa(sx, right);
428 diffy = sa(sx) - sa(sx, bottom);
429 da.set(grad(diffx, diffy), dx);
431 for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
433 diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
434 diffy = sa(sx) - sa(sx, bottom);
435 da.set(grad(diffx, diffy), dx);
438 diffx = sa(sx, left) - sa(sx);
439 diffy = sa(sx) - sa(sx, bottom);
440 da.set(grad(diffx, diffy), dx);
445 for(y=2; y<h; ++y, ++sy.y, ++dy.y)
450 diffx = sa(sx) - sa(sx, right);
451 diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
452 da.set(grad(diffx, diffy), dx);
454 for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
456 diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
457 diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
458 da.set(grad(diffx, diffy), dx);
461 diffx = sa(sx, left) - sa(sx);
462 diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
463 da.set(grad(diffx, diffy), dx);
469 diffx = sa(sx) - sa(sx, right);
470 diffy = sa(sx, top) - sa(sx);
471 da.set(grad(diffx, diffy), dx);
473 for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
475 diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
476 diffy = sa(sx, top) - sa(sx);
477 da.set(grad(diffx, diffy), dx);
480 diffx = sa(sx, left) - sa(sx);
481 diffy = sa(sx, top) - sa(sx);
482 da.set(grad(diffx, diffy), dx);
485 template <
class SrcImageIterator,
class SrcAccessor,
486 class DestImageIterator,
class DestAccessor,
class Functor>
490 pair<DestImageIterator, DestAccessor> dest, Functor
const & grad)
493 dest.first, dest.second, grad);
504 template <
class DestValueType,
class Multiplier =
double>
505 class LinearIntensityTransform
511 typedef DestValueType argument_type;
515 typedef DestValueType result_type;
519 typedef DestValueType value_type;
525 NumericTraits<DestValueType>::RealPromote argument_promote;
529 typedef Multiplier scalar_multiplier_type;
533 LinearIntensityTransform(scalar_multiplier_type scale, argument_promote offset)
534 : scale_(scale), offset_(offset)
539 template <
class SrcValueType>
540 result_type operator()(SrcValueType
const & s)
const
542 return NumericTraits<result_type>::fromRealPromote(scale_ * (s + offset_));
547 scalar_multiplier_type scale_;
548 argument_promote offset_;
551 template <
class DestValueType,
class Multiplier>
552 class FunctorTraits<LinearIntensityTransform<DestValueType, Multiplier> >
553 :
public FunctorTraitsBase<LinearIntensityTransform<DestValueType, Multiplier> >
556 typedef VigraTrueType isUnaryFunctor;
559 template <
class DestValueType,
class Multiplier =
double>
560 class ScalarIntensityTransform
566 typedef DestValueType argument_type;
570 typedef DestValueType result_type;
574 typedef DestValueType value_type;
578 typedef Multiplier scalar_multiplier_type;
582 ScalarIntensityTransform(scalar_multiplier_type scale)
588 template <
class SrcValueType>
589 result_type operator()(SrcValueType
const & s)
const
591 return NumericTraits<result_type>::fromRealPromote(scale_ * s);
595 scalar_multiplier_type scale_;
598 template <
class DestValueType,
class Multiplier>
599 class FunctorTraits<ScalarIntensityTransform<DestValueType, Multiplier> >
600 :
public FunctorTraitsBase<ScalarIntensityTransform<DestValueType, Multiplier> >
603 typedef VigraTrueType isUnaryFunctor;
678 template <
class Multiplier,
class DestValueType>
679 LinearIntensityTransform<DestValueType, Multiplier>
682 return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
685 template <
class DestValueType,
class Multiplier>
686 ScalarIntensityTransform<DestValueType, Multiplier>
689 return ScalarIntensityTransform<DestValueType, Multiplier>(scale);
746 template <
class SrcValueType,
class DestValueType>
747 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
749 DestValueType dest_min, DestValueType dest_max )
752 typename NumericTraits<DestValueType>::isScalar());
755 template <
class SrcValueType,
class DestValueType>
756 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
758 SrcValueType src_min, SrcValueType src_max,
759 DestValueType dest_min, DestValueType dest_max,
762 typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
763 Multiplier diff = src_max - src_min;
764 Multiplier scale = diff == NumericTraits<Multiplier>::zero()
765 ? NumericTraits<Multiplier>::one()
766 : (dest_max - dest_min) / diff;
767 return LinearIntensityTransform<DestValueType, Multiplier>(
768 scale, dest_min / scale - src_min );
771 template <
class SrcValueType,
class DestValueType>
772 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
774 SrcValueType src_min, SrcValueType src_max,
775 DestValueType dest_min, DestValueType dest_max,
778 typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
779 typedef typename Multiplier::value_type MComponent;
780 Multiplier scale(dest_max), offset(dest_max);
781 for(
unsigned int i=0; i<src_min.size(); ++i)
783 MComponent diff = src_max[i] - src_min[i];
784 scale[i] = diff == NumericTraits<MComponent>::zero()
785 ? NumericTraits<MComponent>::one()
786 : (dest_max[i] - dest_min[i]) / diff;
787 offset[i] = dest_min[i] / scale[i] - src_min[i];
789 return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
836 template <
class SrcValueType,
class DestValueType>
853 : lower_(lower), higher_(higher),
854 yesresult_(yesresult), noresult_(noresult)
861 return ((s < lower_) || (higher_ < s)) ? noresult_ : yesresult_;
870 template <
class SrcValueType,
class DestValueType>
871 class FunctorTraits<Threshold<SrcValueType, DestValueType> >
872 :
public FunctorTraitsBase<Threshold<SrcValueType, DestValueType> >
875 typedef VigraTrueType isUnaryFunctor;
957 template <
class PixelType>
961 NumericTraits<PixelType>::RealPromote promote_type;
984 : b_(1.0/brightness),
988 zero_(NumericTraits<promote_type>::zero()),
989 one_(NumericTraits<promote_type>::one())
996 promote_type v1 = (v - min_) / diff_;
998 promote_type v2 = 2.0 * brighter - one_;
999 promote_type contrasted = (v2 < zero_) ?
1002 return result_type(0.5 * diff_ * (contrasted + one_) + min_);
1006 promote_type b_, c_;
1008 promote_type diff_, zero_, one_;
1012 class BrightnessContrastFunctor<unsigned char>
1014 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1015 unsigned char lut[256];
1024 BrightnessContrastFunctor<promote_type> f(brightness, contrast, min, max);
1026 for(
int i = min; i <= max; ++i)
1028 lut[i] =
static_cast<unsigned char>(f(i)+0.5);
1039 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1041 template <
class ComponentType>
1042 class BrightnessContrastFunctor<RGBValue<ComponentType> >
1045 NumericTraits<ComponentType>::RealPromote promote_type;
1046 BrightnessContrastFunctor<ComponentType> red, green, blue;
1054 : red(brightness, contrast, min.red(), max.red()),
1055 green(brightness, contrast, min.green(), max.green()),
1056 blue(brightness, contrast, min.blue(), max.blue())
1062 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1066 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1069 class BrightnessContrastFunctor<RGBValue<int> >
1071 typedef NumericTraits<int>::RealPromote promote_type;
1072 BrightnessContrastFunctor<int> red, green, blue;
1080 : red(brightness, contrast, min.red(), max.red()),
1081 green(brightness, contrast, min.green(), max.green()),
1082 blue(brightness, contrast, min.blue(), max.blue())
1088 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1093 class BrightnessContrastFunctor<RGBValue<float> >
1095 typedef NumericTraits<float>::RealPromote promote_type;
1096 BrightnessContrastFunctor<float> red, green, blue;
1104 : red(brightness, contrast, min.red(), max.red()),
1105 green(brightness, contrast, min.green(), max.green()),
1106 blue(brightness, contrast, min.blue(), max.blue())
1112 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1116 template <
class PixelType>
1117 class FunctorTraits<BrightnessContrastFunctor<PixelType> >
1118 :
public FunctorTraitsBase<BrightnessContrastFunctor<PixelType> >
1121 typedef VigraTrueType isUnaryFunctor;
1124 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1127 class BrightnessContrastFunctor<RGBValue<unsigned char> >
1129 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1130 BrightnessContrastFunctor<unsigned char> red, green, blue;
1139 : red(brightness, contrast, min.red(), max.red()),
1140 green(brightness, contrast, min.green(), max.green()),
1141 blue(brightness, contrast, min.blue(), max.blue())
1147 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1223 template <
class PixelType>
1227 NumericTraits<PixelType>::RealPromote promote_type;
1249 : gamma_((promote_type)gamma),
1252 zero_(NumericTraits<promote_type>::zero()),
1253 one_(NumericTraits<promote_type>::one())
1260 promote_type v1 = (v - min_) / diff_;
1266 promote_type gamma_;
1268 promote_type diff_, zero_, one_;
1272 class GammaFunctor<unsigned char>
1274 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1275 unsigned char lut[256];
1284 GammaFunctor<promote_type> f(gamma, min, max);
1286 for(
int i = min; i <= max; ++i)
1288 lut[i] =
static_cast<unsigned char>(f(i)+0.5);
1299 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1301 template <
class ComponentType>
1302 class GammaFunctor<RGBValue<ComponentType> >
1305 NumericTraits<ComponentType>::RealPromote promote_type;
1306 GammaFunctor<ComponentType> red, green, blue;
1314 : red(gamma, min.red(), max.red()),
1315 green(gamma, min.green(), max.green()),
1316 blue(gamma, min.blue(), max.blue())
1321 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1325 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1328 class GammaFunctor<RGBValue<int> >
1330 typedef NumericTraits<int>::RealPromote promote_type;
1331 GammaFunctor<int> red, green, blue;
1339 : red(gamma, min.red(), max.red()),
1340 green(gamma, min.green(), max.green()),
1341 blue(gamma, min.blue(), max.blue())
1346 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1351 class GammaFunctor<RGBValue<float> >
1353 typedef NumericTraits<float>::RealPromote promote_type;
1354 GammaFunctor<float> red, green, blue;
1362 : red(gamma, min.red(), max.red()),
1363 green(gamma, min.green(), max.green()),
1364 blue(gamma, min.blue(), max.blue())
1369 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1373 template <
class PixelType>
1374 class FunctorTraits<GammaFunctor<PixelType> >
1375 :
public FunctorTraitsBase<GammaFunctor<PixelType> >
1378 typedef VigraTrueType isUnaryFunctor;
1381 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1384 class GammaFunctor<RGBValue<unsigned char> >
1386 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1387 GammaFunctor<unsigned char> red, green, blue;
1395 : red(gamma, min.red(), max.red()),
1396 green(gamma, min.green(), max.green()),
1397 blue(gamma, min.blue(), max.blue())
1402 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1444 template <
class ValueType>
1454 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote
result_type;
1464 template <
class ValueType>
1465 class FunctorTraits<VectorNormFunctor<ValueType> >
1466 :
public FunctorTraitsBase<VectorNormFunctor<ValueType> >
1469 typedef VigraTrueType isUnaryFunctor;
1489 template <
class ValueType>
1499 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote
result_type;
1509 template <
class ValueType>
1510 class FunctorTraits<VectorNormSqFunctor<ValueType> >
1511 :
public FunctorTraitsBase<VectorNormSqFunctor<ValueType> >
1514 typedef VigraTrueType isUnaryFunctor;
1521 #endif // VIGRA_TRANSFORMIMAGE_HXX