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"
62template <
class SrcIterator,
class SrcAccessor,
63 class DestIterator,
class DestAccessor,
class Functor>
65transformLine(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);
74template <
class SrcIterator,
class SrcAccessor,
75 class MaskIterator,
class MaskAccessor,
76 class DestIterator,
class DestAccessor,
79transformLineIf(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);
194template <
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);
212template <
class SrcImageIterator,
class SrcAccessor,
213 class DestImageIterator,
class DestAccessor,
class Functor>
215transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
216 pair<DestImageIterator, DestAccessor> dest,
220 dest.first, dest.second, f);
223template <
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.");
357template <
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);
380template <
class SrcImageIterator,
class SrcAccessor,
381 class MaskImageIterator,
class MaskAccessor,
382 class DestImageIterator,
class DestAccessor,
385transformImageIf(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);
395template <
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.");
512template <
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;
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);
594template <
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);
604template <
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);
624template <
class DestValueType,
class Multiplier =
double>
625class 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_;
671template <
class DestValueType,
class Multiplier>
672class FunctorTraits<LinearIntensityTransform<DestValueType, Multiplier> >
673:
public FunctorTraitsBase<LinearIntensityTransform<DestValueType, Multiplier> >
676 typedef VigraTrueType isUnaryFunctor;
679template <
class DestValueType,
class Multiplier =
double>
680class 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_;
718template <
class DestValueType,
class Multiplier>
719class FunctorTraits<ScalarIntensityTransform<DestValueType, Multiplier> >
720:
public FunctorTraitsBase<ScalarIntensityTransform<DestValueType, Multiplier> >
723 typedef VigraTrueType isUnaryFunctor;
798template <
class Multiplier,
class DestValueType>
799LinearIntensityTransform<DestValueType, Multiplier>
802 return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
805template <
class DestValueType,
class Multiplier>
806ScalarIntensityTransform<DestValueType, Multiplier>
809 return ScalarIntensityTransform<DestValueType, Multiplier>(scale);
880template <
class SrcValueType,
class DestValueType>
881LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
883 DestValueType dest_min, DestValueType dest_max )
886 typename NumericTraits<DestValueType>::isScalar());
889template <
class SrcValueType,
class DestValueType>
890LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
892 DestValueType dest_min, DestValueType dest_max )
895 typename NumericTraits<DestValueType>::isScalar());
898template <
class SrcValueType,
class DestValueType>
899LinearIntensityTransform<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 );
914template <
class SrcValueType,
class DestValueType>
915LinearIntensityTransform<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);
982template <
class SrcValueType,
class DestValueType>
999 : lower_(lower), higher_(higher),
1000 yesresult_(yesresult), noresult_(noresult)
1007 return ((s < lower_) || (higher_ < s)) ? noresult_ : yesresult_;
1016template <
class SrcValueType,
class DestValueType>
1017class FunctorTraits<Threshold<SrcValueType, DestValueType> >
1018:
public FunctorTraitsBase<Threshold<SrcValueType, DestValueType> >
1021 typedef VigraTrueType isUnaryFunctor;
1103template <
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_;
1158class BrightnessContrastFunctor<unsigned char>
1160 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1161 unsigned char lut[256];
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
1187template <
class ComponentType>
1188class 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()));
1215class BrightnessContrastFunctor<RGBValue<int> >
1217 typedef NumericTraits<int>::RealPromote promote_type;
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()));
1239class BrightnessContrastFunctor<RGBValue<float> >
1241 typedef NumericTraits<float>::RealPromote promote_type;
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()));
1262template <
class PixelType>
1263class FunctorTraits<BrightnessContrastFunctor<PixelType> >
1264:
public FunctorTraitsBase<BrightnessContrastFunctor<PixelType> >
1267 typedef VigraTrueType isUnaryFunctor;
1273class 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()));
1369template <
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_;
1418class GammaFunctor<unsigned char>
1420 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1421 unsigned char lut[256];
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
1447template <
class ComponentType>
1448class 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()));
1474class GammaFunctor<RGBValue<int> >
1476 typedef NumericTraits<int>::RealPromote promote_type;
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()));
1497class GammaFunctor<RGBValue<float> >
1499 typedef NumericTraits<float>::RealPromote promote_type;
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()));
1519template <
class PixelType>
1520class FunctorTraits<GammaFunctor<PixelType> >
1521:
public FunctorTraitsBase<GammaFunctor<PixelType> >
1524 typedef VigraTrueType isUnaryFunctor;
1530class 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()));
1590template <
class ValueType>
1600 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote
result_type;
1606 return VIGRA_CSTD::sqrt(
dot(a,a) );
1610template <
class ValueType>
1611class FunctorTraits<VectorNormFunctor<ValueType> >
1612:
public FunctorTraitsBase<VectorNormFunctor<ValueType> >
1615 typedef VigraTrueType isUnaryFunctor;
1635template <
class ValueType>
1645 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote
result_type;
1655template <
class ValueType>
1656class FunctorTraits<VectorNormSqFunctor<ValueType> >
1657:
public FunctorTraitsBase<VectorNormSqFunctor<ValueType> >
1660 typedef VigraTrueType isUnaryFunctor;
Adjust brightness and contrast of an image.
Definition transformimage.hxx:1105
PixelType argument_type
Definition transformimage.hxx:1113
BrightnessContrastFunctor(promote_type brightness, promote_type contrast, argument_type const &min, argument_type const &max)
Definition transformimage.hxx:1128
PixelType result_type
Definition transformimage.hxx:1117
PixelType value_type
Definition transformimage.hxx:1121
result_type operator()(argument_type const &v) const
Definition transformimage.hxx:1140
Two dimensional difference vector.
Definition diff2d.hxx:186
Perform gamma correction of an image.
Definition transformimage.hxx:1371
PixelType argument_type
Definition transformimage.hxx:1379
PixelType result_type
Definition transformimage.hxx:1383
PixelType value_type
Definition transformimage.hxx:1387
GammaFunctor(double gamma, argument_type const &min, argument_type const &max)
Definition transformimage.hxx:1393
result_type operator()(argument_type const &v) const
Definition transformimage.hxx:1404
Threshold an image.
Definition transformimage.hxx:984
Threshold(argument_type lower, argument_type higher, result_type noresult, result_type yesresult)
Definition transformimage.hxx:997
DestValueType result_type
Definition transformimage.hxx:993
result_type operator()(argument_type s) const
Definition transformimage.hxx:1005
SrcValueType argument_type
Definition transformimage.hxx:989
A functor for computing the vector norm.
Definition transformimage.hxx:1592
result_type operator()(const argument_type &a) const
Definition transformimage.hxx:1604
NumericTraits< typenameValueType::value_type >::RealPromote result_type
Definition transformimage.hxx:1600
ValueType argument_type
Definition transformimage.hxx:1596
A functor for computing the squared vector norm.
Definition transformimage.hxx:1637
result_type operator()(const argument_type &a) const
Definition transformimage.hxx:1649
NumericTraits< typenameValueType::value_type >::RealPromote result_type
Definition transformimage.hxx:1645
ValueType argument_type
Definition transformimage.hxx:1641
double gamma(double x)
The gamma function.
Definition mathutil.hxx:1587
LinearIntensityTransform< DestValueType, Multiplier > linearIntensityTransform(Multiplier scale, DestValueType offset)
Apply a linear transform to the source pixel values.
Definition transformimage.hxx:800
LinearIntensityTransform< DestValueType, typename NumericTraits< DestValueType >::RealPromote > linearRangeMapping(SrcValueType src_min, SrcValueType src_max, DestValueType dest_min, DestValueType dest_max)
Map a source intensity range linearly to a destination range.
Definition transformimage.hxx:882
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