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