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" 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);
192 doxygen_overloaded_function(template <...>
void transformImage)
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.");
355 doxygen_overloaded_function(template <...>
void transformImageIf)
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.");
510 doxygen_overloaded_function(template <...>
void gradientBasedTransform)
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);
979 template <
class SrcValueType,
class DestValueType>
995 result_type noresult, result_type yesresult)
996 : lower_(lower), higher_(higher),
997 yesresult_(yesresult), noresult_(noresult)
1004 return ((s < lower_) || (higher_ < s)) ? noresult_ : yesresult_;
1009 argument_type lower_, higher_;
1010 result_type yesresult_, noresult_;
1013 template <
class SrcValueType,
class DestValueType>
1014 class FunctorTraits<Threshold<SrcValueType, DestValueType> >
1015 :
public FunctorTraitsBase<Threshold<SrcValueType, DestValueType> >
1018 typedef VigraTrueType isUnaryFunctor;
1100 template <
class PixelType>
1104 NumericTraits<PixelType>::RealPromote promote_type;
1126 argument_type
const & min, argument_type
const & max)
1127 : b_(1.0/brightness),
1131 zero_(NumericTraits<promote_type>::zero()),
1132 one_(NumericTraits<promote_type>::one())
1139 promote_type v1 = (v - min_) / diff_;
1140 promote_type brighter = VIGRA_CSTD::pow(v1, b_);
1141 promote_type v2 = 2.0 * brighter - one_;
1142 promote_type contrasted = (v2 < zero_) ?
1143 -VIGRA_CSTD::pow(-v2, c_) :
1144 VIGRA_CSTD::pow(v2, c_);
1145 return result_type(0.5 * diff_ * (contrasted + one_) + min_);
1149 promote_type b_, c_;
1151 promote_type diff_, zero_, one_;
1157 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1158 unsigned char lut[256];
1162 typedef unsigned char value_type;
1165 value_type
const & min = 0, value_type
const & max = 255)
1169 for(
int i = min; i <= max; ++i)
1171 lut[i] =
static_cast<unsigned char>(f(i)+0.5);
1175 value_type operator()(value_type
const & v)
const 1182 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 1184 template <
class ComponentType>
1188 NumericTraits<ComponentType>::RealPromote promote_type;
1196 value_type
const & min, value_type
const & max)
1197 : red(brightness, contrast, min.red(), max.red()),
1198 green(brightness, contrast, min.green(), max.green()),
1199 blue(brightness, contrast, min.blue(), max.blue())
1202 value_type operator()(value_type
const & v)
const 1205 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1209 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION 1214 typedef NumericTraits<int>::RealPromote promote_type;
1222 value_type
const & min, value_type
const & max)
1223 : red(brightness, contrast, min.red(), max.red()),
1224 green(brightness, contrast, min.green(), max.green()),
1225 blue(brightness, contrast, min.blue(), max.blue())
1228 value_type operator()(value_type
const & v)
const 1231 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1238 typedef NumericTraits<float>::RealPromote promote_type;
1246 value_type
const & min, value_type
const & max)
1247 : red(brightness, contrast, min.red(), max.red()),
1248 green(brightness, contrast, min.green(), max.green()),
1249 blue(brightness, contrast, min.blue(), max.blue())
1252 value_type operator()(value_type
const & v)
const 1255 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1259 template <
class PixelType>
1261 :
public FunctorTraitsBase<BrightnessContrastFunctor<PixelType> >
1264 typedef VigraTrueType isUnaryFunctor;
1267 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 1270 class BrightnessContrastFunctor<RGBValue<unsigned char> >
1272 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1279 BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
1280 value_type
const & min = value_type(0,0,0),
1281 value_type
const & max = value_type(255, 255, 255))
1282 : red(brightness, contrast, min.red(), max.red()),
1283 green(brightness, contrast, min.green(), max.green()),
1284 blue(brightness, contrast, min.blue(), max.blue())
1287 value_type operator()(value_type
const & v)
const 1290 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1366 template <
class PixelType>
1370 NumericTraits<PixelType>::RealPromote promote_type;
1391 argument_type
const & min, argument_type
const & max)
1392 : gamma_((promote_type)gamma),
1395 zero_(NumericTraits<promote_type>::zero()),
1396 one_(NumericTraits<promote_type>::one())
1403 promote_type v1 = (v - min_) / diff_;
1404 promote_type brighter = VIGRA_CSTD::pow(v1, gamma_);
1405 return result_type(diff_ * brighter + min_);
1409 promote_type gamma_;
1411 promote_type diff_, zero_, one_;
1417 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1418 unsigned char lut[256];
1422 typedef unsigned char value_type;
1425 value_type
const & min = 0, value_type
const & max = 255)
1429 for(
int i = min; i <= max; ++i)
1431 lut[i] =
static_cast<unsigned char>(f(i)+0.5);
1435 value_type operator()(value_type
const & v)
const 1442 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 1444 template <
class ComponentType>
1448 NumericTraits<ComponentType>::RealPromote promote_type;
1456 value_type
const & min, value_type
const & max)
1457 : red(gamma, min.red(), max.red()),
1458 green(gamma, min.green(), max.green()),
1459 blue(gamma, min.blue(), max.blue())
1462 value_type operator()(value_type
const & v)
const 1464 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1468 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION 1473 typedef NumericTraits<int>::RealPromote promote_type;
1481 value_type
const & min, value_type
const & max)
1482 : red(gamma, min.red(), max.red()),
1483 green(gamma, min.green(), max.green()),
1484 blue(gamma, min.blue(), max.blue())
1487 value_type operator()(value_type
const & v)
const 1489 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1496 typedef NumericTraits<float>::RealPromote promote_type;
1504 value_type
const & min, value_type
const & max)
1505 : red(gamma, min.red(), max.red()),
1506 green(gamma, min.green(), max.green()),
1507 blue(gamma, min.blue(), max.blue())
1510 value_type operator()(value_type
const & v)
const 1512 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1516 template <
class PixelType>
1518 :
public FunctorTraitsBase<GammaFunctor<PixelType> >
1521 typedef VigraTrueType isUnaryFunctor;
1524 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 1527 class GammaFunctor<RGBValue<unsigned char> >
1529 typedef NumericTraits<unsigned char>::RealPromote promote_type;
1535 GammaFunctor(promote_type
gamma,
1536 value_type
const & min = value_type(0,0,0),
1537 value_type
const & max = value_type(255, 255, 255))
1538 : red(gamma, min.red(), max.red()),
1539 green(gamma, min.green(), max.green()),
1540 blue(gamma, min.blue(), max.blue())
1543 value_type operator()(value_type
const & v)
const 1545 return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1587 template <
class ValueType>
1597 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote
result_type;
1607 template <
class ValueType>
1609 :
public FunctorTraitsBase<VectorNormFunctor<ValueType> >
1612 typedef VigraTrueType isUnaryFunctor;
1632 template <
class ValueType>
1642 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote
result_type;
1652 template <
class ValueType>
1654 :
public FunctorTraitsBase<VectorNormSqFunctor<ValueType> >
1657 typedef VigraTrueType isUnaryFunctor;
1664 #endif // VIGRA_TRANSFORMIMAGE_HXX NumericTraits< typename ValueType::value_type >::RealPromote result_type
Definition: transformimage.hxx:1597
PixelType argument_type
Definition: transformimage.hxx:1376
A functor for computing the squared vector norm.
Definition: transformimage.hxx:1633
PixelType argument_type
Definition: transformimage.hxx:1110
NumericTraits< typename ValueType::value_type >::RealPromote result_type
Definition: transformimage.hxx:1642
Adjust brightness and contrast of an image.
Definition: transformimage.hxx:1101
VALUETYPE min
Definition: inspectimage.hxx:1080
Export associated information for a functor.
Definition: functortraits.hxx:157
result_type operator()(argument_type s) const
Definition: transformimage.hxx:1002
Definition: accessor.hxx:43
GammaFunctor(double gamma, argument_type const &min, argument_type const &max)
Definition: transformimage.hxx:1390
SrcValueType argument_type
Definition: transformimage.hxx:986
ValueType argument_type
Definition: transformimage.hxx:1638
PixelType result_type
Definition: transformimage.hxx:1380
A functor for computing the vector norm.
Definition: transformimage.hxx:1588
PixelType result_type
Definition: transformimage.hxx:1114
result_type operator()(const argument_type &a) const
Definition: transformimage.hxx:1601
Find the minimum and maximum pixel value in an image or ROI.
Definition: inspectimage.hxx:1001
result_type operator()(argument_type const &v) const
Definition: transformimage.hxx:1401
Threshold(argument_type lower, argument_type higher, result_type noresult, result_type yesresult)
Definition: transformimage.hxx:994
ValueType argument_type
Definition: transformimage.hxx:1593
BrightnessContrastFunctor(promote_type brightness, promote_type contrast, argument_type const &min, argument_type const &max)
Definition: transformimage.hxx:1125
PixelType value_type
Definition: transformimage.hxx:1384
NormTraits< T >::SquaredNormType dot(const MultiArrayView< 2, T, C1 > &x, const MultiArrayView< 2, T, C2 > &y)
Definition: matrix.hxx:1340
double gamma(double x)
The gamma function.
Definition: mathutil.hxx:1549
PixelType value_type
Definition: transformimage.hxx:1118
Perform gamma correction of an image.
Definition: transformimage.hxx:1367
result_type operator()(const argument_type &a) const
Definition: transformimage.hxx:1646
Threshold an image.
Definition: transformimage.hxx:980
result_type operator()(argument_type const &v) const
Definition: transformimage.hxx:1137
VALUETYPE max
Definition: inspectimage.hxx:1084
DestValueType result_type
Definition: transformimage.hxx:990
Class for a single RGB value.
Definition: accessor.hxx:938
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616