37 #ifndef VIGRA_TRANSFORMIMAGE_HXX
38 #define VIGRA_TRANSFORMIMAGE_HXX
41 #include "numerictraits.hxx"
42 #include "iteratortraits.hxx"
43 #include "rgbvalue.hxx"
44 #include "functortraits.hxx"
45 #include "inspectimage.hxx"
46 #include "multi_shape.hxx"
62 template <
class SrcIterator,
class SrcAccessor,
63 class DestIterator,
class DestAccessor,
class Functor>
65 transformLine(SrcIterator s,
66 SrcIterator send, SrcAccessor src,
67 DestIterator d, DestAccessor dest,
70 for(; s != send; ++s, ++d)
71 dest.set(f(src(s)), d);
74 template <
class SrcIterator,
class SrcAccessor,
75 class MaskIterator,
class MaskAccessor,
76 class DestIterator,
class DestAccessor,
79 transformLineIf(SrcIterator s,
80 SrcIterator send, SrcAccessor src,
81 MaskIterator m, MaskAccessor mask,
82 DestIterator d, DestAccessor dest,
85 for(; s != send; ++s, ++d, ++m)
87 dest.set(f(src(s)), d);
194 template <
class SrcImageIterator,
class SrcAccessor,
195 class DestImageIterator,
class DestAccessor,
class Functor>
198 SrcImageIterator src_lowerright, SrcAccessor sa,
199 DestImageIterator dest_upperleft, DestAccessor da,
202 int w = src_lowerright.x - src_upperleft.x;
204 for(; src_upperleft.y < src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y)
206 transformLine(src_upperleft.rowIterator(),
207 src_upperleft.rowIterator() + w, sa,
208 dest_upperleft.rowIterator(), da, f);
212 template <
class SrcImageIterator,
class SrcAccessor,
213 class DestImageIterator,
class DestAccessor,
class Functor>
215 transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
216 pair<DestImageIterator, DestAccessor> dest,
220 dest.first, dest.second, f);
223 template <
class T1,
class S1,
224 class T2,
class S2,
class Functor>
227 MultiArrayView<2, T2, S2> dest,
230 vigra_precondition(src.shape() == dest.shape(),
231 "transformImage(): shape mismatch between input and output.");
357 template <
class SrcImageIterator,
class SrcAccessor,
358 class MaskImageIterator,
class MaskAccessor,
359 class DestImageIterator,
class DestAccessor,
363 SrcImageIterator src_lowerright, SrcAccessor sa,
364 MaskImageIterator mask_upperleft, MaskAccessor ma,
365 DestImageIterator dest_upperleft, DestAccessor da,
368 int w = src_lowerright.x - src_upperleft.x;
370 for(; src_upperleft.y < src_lowerright.y;
371 ++src_upperleft.y, ++mask_upperleft.y, ++dest_upperleft.y)
373 transformLineIf(src_upperleft.rowIterator(),
374 src_upperleft.rowIterator() + w, sa,
375 mask_upperleft.rowIterator(), ma,
376 dest_upperleft.rowIterator(), da, f);
380 template <
class SrcImageIterator,
class SrcAccessor,
381 class MaskImageIterator,
class MaskAccessor,
382 class DestImageIterator,
class DestAccessor,
385 transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
386 pair<MaskImageIterator, MaskAccessor> mask,
387 pair<DestImageIterator, DestAccessor> dest,
391 mask.first, mask.second,
392 dest.first, dest.second, f);
395 template <
class T1,
class S1,
401 MultiArrayView<2, TM, SM>
const & mask,
402 MultiArrayView<2, T2, S2> dest,
405 vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
406 "transformImageIf(): shape mismatch between input and output.");
512 template <
class SrcImageIterator,
class SrcAccessor,
513 class DestImageIterator,
class DestAccessor,
class Functor>
516 DestImageIterator destul, DestAccessor da, Functor
const & grad)
518 int w = srclr.x - srcul.x;
519 int h = srclr.y - srcul.y;
522 SrcImageIterator sy = srcul;
523 DestImageIterator dy = destul;
525 const Diff2D left(-1,0);
526 const Diff2D right(1,0);
527 const Diff2D top(0,-1);
528 const Diff2D bottom(0,1);
530 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
531 TmpType diffx, diffy;
533 SrcImageIterator sx = sy;
534 DestImageIterator dx = dy;
536 diffx = sa(sx) - sa(sx, right);
537 diffy = sa(sx) - sa(sx, bottom);
538 da.set(grad(diffx, diffy), dx);
540 for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
542 diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
543 diffy = sa(sx) - sa(sx, bottom);
544 da.set(grad(diffx, diffy), dx);
547 diffx = sa(sx, left) - sa(sx);
548 diffy = sa(sx) - sa(sx, bottom);
549 da.set(grad(diffx, diffy), dx);
554 for(y=2; y<h; ++y, ++sy.y, ++dy.y)
559 diffx = sa(sx) - sa(sx, right);
560 diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
561 da.set(grad(diffx, diffy), dx);
563 for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
565 diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
566 diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
567 da.set(grad(diffx, diffy), dx);
570 diffx = sa(sx, left) - sa(sx);
571 diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
572 da.set(grad(diffx, diffy), dx);
578 diffx = sa(sx) - sa(sx, right);
579 diffy = sa(sx, top) - sa(sx);
580 da.set(grad(diffx, diffy), dx);
582 for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
584 diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
585 diffy = sa(sx, top) - sa(sx);
586 da.set(grad(diffx, diffy), dx);
589 diffx = sa(sx, left) - sa(sx);
590 diffy = sa(sx, top) - sa(sx);
591 da.set(grad(diffx, diffy), dx);
594 template <
class SrcImageIterator,
class SrcAccessor,
595 class DestImageIterator,
class DestAccessor,
class Functor>
598 pair<DestImageIterator, DestAccessor> dest, Functor
const & grad)
601 dest.first, dest.second, grad);
604 template <
class T1,
class S1,
605 class T2,
class S2,
class Functor>
608 MultiArrayView<2, T2, S2> dest, Functor
const & grad)
610 vigra_precondition(src.shape() == dest.shape(),
611 "gradientBasedTransform(): shape mismatch between input and output.");
613 destImage(dest), grad);
624 template <
class DestValueType,
class Multiplier =
double>
625 class LinearIntensityTransform
631 typedef DestValueType argument_type;
635 typedef DestValueType result_type;
639 typedef DestValueType value_type;
645 NumericTraits<DestValueType>::RealPromote argument_promote;
649 typedef Multiplier scalar_multiplier_type;
653 LinearIntensityTransform(scalar_multiplier_type scale, argument_promote offset)
654 : scale_(scale), offset_(offset)
659 template <
class SrcValueType>
660 result_type operator()(SrcValueType
const & s)
const
662 return NumericTraits<result_type>::fromRealPromote(scale_ * (s + offset_));
667 scalar_multiplier_type scale_;
668 argument_promote offset_;
671 template <
class DestValueType,
class Multiplier>
672 class FunctorTraits<LinearIntensityTransform<DestValueType, Multiplier> >
673 :
public FunctorTraitsBase<LinearIntensityTransform<DestValueType, Multiplier> >
676 typedef VigraTrueType isUnaryFunctor;
679 template <
class DestValueType,
class Multiplier =
double>
680 class ScalarIntensityTransform
686 typedef DestValueType argument_type;
690 typedef DestValueType result_type;
694 typedef DestValueType value_type;
698 typedef Multiplier scalar_multiplier_type;
702 ScalarIntensityTransform(scalar_multiplier_type scale)
708 template <
class SrcValueType>
709 result_type operator()(SrcValueType
const & s)
const
711 return NumericTraits<result_type>::fromRealPromote(scale_ * s);
715 scalar_multiplier_type scale_;
718 template <
class DestValueType,
class Multiplier>
719 class FunctorTraits<ScalarIntensityTransform<DestValueType, Multiplier> >
720 :
public FunctorTraitsBase<ScalarIntensityTransform<DestValueType, Multiplier> >
723 typedef VigraTrueType isUnaryFunctor;
798 template <
class Multiplier,
class DestValueType>
799 LinearIntensityTransform<DestValueType, Multiplier>
802 return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
805 template <
class DestValueType,
class Multiplier>
806 ScalarIntensityTransform<DestValueType, Multiplier>
809 return ScalarIntensityTransform<DestValueType, Multiplier>(scale);
880 template <
class SrcValueType,
class DestValueType>
881 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
883 DestValueType dest_min, DestValueType dest_max )
886 typename NumericTraits<DestValueType>::isScalar());
889 template <
class SrcValueType,
class DestValueType>
890 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
892 DestValueType dest_min, DestValueType dest_max )
895 typename NumericTraits<DestValueType>::isScalar());
898 template <
class SrcValueType,
class DestValueType>
899 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
901 SrcValueType src_min, SrcValueType src_max,
902 DestValueType dest_min, DestValueType dest_max,
905 typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
906 Multiplier diff = src_max - src_min;
907 Multiplier scale = diff == NumericTraits<Multiplier>::zero()
908 ? NumericTraits<Multiplier>::one()
909 : (dest_max - dest_min) / diff;
910 return LinearIntensityTransform<DestValueType, Multiplier>(
911 scale, dest_min / scale - src_min );
914 template <
class SrcValueType,
class DestValueType>
915 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
917 SrcValueType src_min, SrcValueType src_max,
918 DestValueType dest_min, DestValueType dest_max,
921 typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
922 typedef typename Multiplier::value_type MComponent;
923 Multiplier scale(dest_max), offset(dest_max);
924 for(
unsigned int i=0; i<src_min.size(); ++i)
926 MComponent diff = src_max[i] - src_min[i];
927 scale[i] = diff == NumericTraits<MComponent>::zero()
928 ? NumericTraits<MComponent>::one()
929 : (dest_max[i] - dest_min[i]) / diff;
930 offset[i] = dest_min[i] / scale[i] - src_min[i];
932 return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
982 template <
class SrcValueType,
class DestValueType>
999 : lower_(lower), higher_(higher),
1000 yesresult_(yesresult), noresult_(noresult)
1007 return ((s < lower_) || (higher_ < s)) ? noresult_ : yesresult_;
1016 template <
class SrcValueType,
class DestValueType>
1017 class FunctorTraits<Threshold<SrcValueType, DestValueType> >
1018 :
public FunctorTraitsBase<Threshold<SrcValueType, DestValueType> >
1021 typedef VigraTrueType isUnaryFunctor;
1103 template <
class PixelType>
1107 NumericTraits<PixelType>::RealPromote promote_type;
1130 : b_(1.0/brightness),
1134 zero_(NumericTraits<promote_type>::zero()),
1135 one_(NumericTraits<promote_type>::one())
1142 promote_type v1 = (v - min_) / diff_;
1143 promote_type brighter = VIGRA_CSTD::pow(v1, b_);
1144 promote_type v2 = 2.0 * brighter - one_;
1145 promote_type contrasted = (v2 < zero_) ?
1146 -VIGRA_CSTD::pow(-v2, c_) :
1147 VIGRA_CSTD::pow(v2, c_);
1148 return result_type(0.5 * diff_ * (contrasted + one_) + min_);
1152 promote_type b_, c_;
1154 promote_type diff_, zero_, one_;
1158 class BrightnessContrastFunctor<unsigned char>
1160 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1161 unsigned char lut[256];
1170 BrightnessContrastFunctor<promote_type> f(brightness, contrast, min, max);
1172 for(
int i = min; i <= max; ++i)
1174 lut[i] =
static_cast<unsigned char>(f(i)+0.5);
1185 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1187 template <
class ComponentType>
1188 class BrightnessContrastFunctor<RGBValue<ComponentType> >
1191 NumericTraits<ComponentType>::RealPromote promote_type;
1192 BrightnessContrastFunctor<ComponentType> red, green, blue;
1200 : red(brightness, contrast, min.red(), max.red()),
1201 green(brightness, contrast, min.green(), max.green()),
1202 blue(brightness, contrast, min.blue(), max.blue())
1208 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1212 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1215 class BrightnessContrastFunctor<RGBValue<int> >
1217 typedef NumericTraits<int>::RealPromote promote_type;
1218 BrightnessContrastFunctor<int> red, green, blue;
1226 : red(brightness, contrast, min.red(), max.red()),
1227 green(brightness, contrast, min.green(), max.green()),
1228 blue(brightness, contrast, min.blue(), max.blue())
1234 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1239 class BrightnessContrastFunctor<RGBValue<float> >
1241 typedef NumericTraits<float>::RealPromote promote_type;
1242 BrightnessContrastFunctor<float> red, green, blue;
1250 : red(brightness, contrast, min.red(), max.red()),
1251 green(brightness, contrast, min.green(), max.green()),
1252 blue(brightness, contrast, min.blue(), max.blue())
1258 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1262 template <
class PixelType>
1263 class FunctorTraits<BrightnessContrastFunctor<PixelType> >
1264 :
public FunctorTraitsBase<BrightnessContrastFunctor<PixelType> >
1267 typedef VigraTrueType isUnaryFunctor;
1270 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1273 class BrightnessContrastFunctor<RGBValue<unsigned char> >
1275 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1276 BrightnessContrastFunctor<unsigned char> red, green, blue;
1285 : red(brightness, contrast, min.red(), max.red()),
1286 green(brightness, contrast, min.green(), max.green()),
1287 blue(brightness, contrast, min.blue(), max.blue())
1293 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1369 template <
class PixelType>
1373 NumericTraits<PixelType>::RealPromote promote_type;
1395 : gamma_((promote_type)gamma),
1398 zero_(NumericTraits<promote_type>::zero()),
1399 one_(NumericTraits<promote_type>::one())
1406 promote_type v1 = (v - min_) / diff_;
1407 promote_type brighter = VIGRA_CSTD::pow(v1, gamma_);
1412 promote_type gamma_;
1414 promote_type diff_, zero_, one_;
1418 class GammaFunctor<unsigned char>
1420 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1421 unsigned char lut[256];
1430 GammaFunctor<promote_type> f(gamma, min, max);
1432 for(
int i = min; i <= max; ++i)
1434 lut[i] =
static_cast<unsigned char>(f(i)+0.5);
1445 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1447 template <
class ComponentType>
1448 class GammaFunctor<RGBValue<ComponentType> >
1451 NumericTraits<ComponentType>::RealPromote promote_type;
1452 GammaFunctor<ComponentType> red, green, blue;
1460 : red(gamma, min.red(), max.red()),
1461 green(gamma, min.green(), max.green()),
1462 blue(gamma, min.blue(), max.blue())
1467 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1471 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1474 class GammaFunctor<RGBValue<int> >
1476 typedef NumericTraits<int>::RealPromote promote_type;
1477 GammaFunctor<int> red, green, blue;
1485 : red(gamma, min.red(), max.red()),
1486 green(gamma, min.green(), max.green()),
1487 blue(gamma, min.blue(), max.blue())
1492 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1497 class GammaFunctor<RGBValue<float> >
1499 typedef NumericTraits<float>::RealPromote promote_type;
1500 GammaFunctor<float> red, green, blue;
1508 : red(gamma, min.red(), max.red()),
1509 green(gamma, min.green(), max.green()),
1510 blue(gamma, min.blue(), max.blue())
1515 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1519 template <
class PixelType>
1520 class FunctorTraits<GammaFunctor<PixelType> >
1521 :
public FunctorTraitsBase<GammaFunctor<PixelType> >
1524 typedef VigraTrueType isUnaryFunctor;
1527 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1530 class GammaFunctor<RGBValue<unsigned char> >
1532 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1533 GammaFunctor<unsigned char> red, green, blue;
1541 : red(gamma, min.red(), max.red()),
1542 green(gamma, min.green(), max.green()),
1543 blue(gamma, min.blue(), max.blue())
1548 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1590 template <
class ValueType>
1600 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote
result_type;
1610 template <
class ValueType>
1611 class FunctorTraits<VectorNormFunctor<ValueType> >
1612 :
public FunctorTraitsBase<VectorNormFunctor<ValueType> >
1615 typedef VigraTrueType isUnaryFunctor;
1635 template <
class ValueType>
1645 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote
result_type;
1655 template <
class ValueType>
1656 class FunctorTraits<VectorNormSqFunctor<ValueType> >
1657 :
public FunctorTraitsBase<VectorNormSqFunctor<ValueType> >
1660 typedef VigraTrueType isUnaryFunctor;
1667 #endif // VIGRA_TRANSFORMIMAGE_HXX
NumericTraits< typename ValueType::value_type >::RealPromote result_type
Definition: transformimage.hxx:1600
PixelType argument_type
Definition: transformimage.hxx:1379
A functor for computing the squared vector norm.
Definition: transformimage.hxx:1636
PromoteTraits< V1, V2 >::Promote dot(RGBValue< V1, RIDX1, GIDX1, BIDX1 > const &r1, RGBValue< V2, RIDX2, GIDX2, BIDX2 > const &r2)
dot product
Definition: rgbvalue.hxx:906
PixelType argument_type
Definition: transformimage.hxx:1113
NumericTraits< typename ValueType::value_type >::RealPromote result_type
Definition: transformimage.hxx:1645
Adjust brightness and contrast of an image.
Definition: transformimage.hxx:1104
result_type operator()(argument_type s) const
Definition: transformimage.hxx:1005
GammaFunctor(double gamma, argument_type const &min, argument_type const &max)
Definition: transformimage.hxx:1393
SrcValueType argument_type
Definition: transformimage.hxx:989
ValueType argument_type
Definition: transformimage.hxx:1641
PixelType result_type
Definition: transformimage.hxx:1383
A functor for computing the vector norm.
Definition: transformimage.hxx:1591
PixelType result_type
Definition: transformimage.hxx:1117
result_type operator()(const argument_type &a) const
Definition: transformimage.hxx:1604
result_type operator()(argument_type const &v) const
Definition: transformimage.hxx:1404
Threshold(argument_type lower, argument_type higher, result_type noresult, result_type yesresult)
Definition: transformimage.hxx:997
ValueType argument_type
Definition: transformimage.hxx:1596
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
BrightnessContrastFunctor(promote_type brightness, promote_type contrast, argument_type const &min, argument_type const &max)
Definition: transformimage.hxx:1128
PixelType value_type
Definition: transformimage.hxx:1387
double gamma(double x)
The gamma function.
Definition: mathutil.hxx:1587
PixelType value_type
Definition: transformimage.hxx:1121
Perform gamma correction of an image.
Definition: transformimage.hxx:1370
result_type operator()(const argument_type &a) const
Definition: transformimage.hxx:1649
Threshold an image.
Definition: transformimage.hxx:983
result_type operator()(argument_type const &v) const
Definition: transformimage.hxx:1140
DestValueType result_type
Definition: transformimage.hxx:993
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616