26 #ifndef VIGRA_EXT_UTILS_H
27 #define VIGRA_EXT_UTILS_H
30 #include <vigra/rgbvalue.hxx>
31 #include <vigra/transformimage.hxx>
32 #include <vigra/codec.hxx>
37 template <
class T1,
unsigned int R,
unsigned int G,
unsigned int B,
class T2>
38 struct PromoteTraits<RGBValue<T1, R, G, B>, T2 >
40 typedef RGBValue<typename PromoteTraits<T1, T2>::Promote>
Promote;
49 #define LUT_TRAITS(T1, Smin, Smax) \
51 struct LUTTraits<T1> \
63 struct LUTTraits<vigra::RGBValue<T1> > \
93 }
else if (v ==
"INT8") {
95 }
else if (v ==
"UINT16") {
97 }
else if (v ==
"INT16") {
99 }
else if (v ==
"UINT32") {
101 }
else if (v ==
"INT32") {
107 template <
class VALUE>
116 :
imgNr1(img1),
i1(val1), p1(p1), r1(r1),
imgNr2(img2),
i2(val2), p2(p2), r2(r2)
136 #define VT_TRAITS_VEC(T1) \
138 struct ValueTypeTraits<vigra::RGBValue<T1, 0u, 1u, 2u> > \
140 typedef vigra::RGBValue<T1, 0u, 1u, 2u>::value_type value_type; \
143 #define VT_TRAITS(T1) \
145 struct ValueTypeTraits<T1> \
147 typedef T1 value_type; \
181 inline float pow(
float a,
double b)
187 template <
class T,
unsigned int R,
unsigned int G,
unsigned int B>
189 vigra::RGBValue<T, R, G, B>
pow(vigra::RGBValue<T, R, G, B>
const & v,
double e) {
190 return vigra::RGBValue<T, R, G, B>(
pow(v.red(),e),
pow(v.green(),e),
pow(v.blue(),e));
194 template <
class V1,
unsigned int R,
unsigned int G,
unsigned int B,
class V2>
196 vigra::RGBValue<V1, R, G, B> &
206 template <
class T,
unsigned int RIDX,
unsigned int GIDX,
unsigned int BIDX>
208 vigra::RGBValue<T, RIDX, GIDX, BIDX>
209 log(vigra::RGBValue<T, RIDX, GIDX, BIDX>
const & v)
215 template <
class T,
unsigned int RIDX,
unsigned int GIDX,
unsigned int BIDX>
217 vigra::RGBValue<T, RIDX, GIDX, BIDX>
218 log10(vigra::RGBValue<T, RIDX, GIDX, BIDX>
const & v)
224 template <
class V1,
unsigned int R,
unsigned int G,
unsigned int B,
class V2>
228 typename vigra::PromoteTraits<vigra::RGBValue<V1, R, G, B>, V2 >::Promote
229 operator+(vigra::RGBValue<V1, R, G, B>
const & r1, V2
const & r2)
231 typename vigra::PromoteTraits<vigra::RGBValue<V1, R, G, B>, V2 >::Promote res(r1);
240 template <
class V,
int SIZE,
class D1,
class D2>
242 vigra::TinyVector<V, SIZE>
243 pow(vigra::TinyVector<V, SIZE>
const & v,
double e)
245 vigra::TinyVector<V, SIZE> res;
246 for (
int i=0; i<SIZE; i++)
253 template <
class V,
int SIZE,
class D1,
class D2>
255 vigra::TinyVector<V, SIZE>
256 log(vigra::TinyVector<V, SIZE>
const & v,
double e)
258 vigra::TinyVector<V, SIZE> res;
259 for (
int i=0; i<SIZE; i++)
300 template <
class VALUETYPE>
369 template<
class ImgIter,
class ImgAccessor,
class AlphaIter,
class AlphaAccessor>
370 void applyExposureClipMask(vigra::triple<ImgIter, ImgIter, ImgAccessor> image, vigra::triple<AlphaIter, AlphaIter, AlphaAccessor> mask,
double lowerLimit,
double upperLimit)
372 typedef typename ImgAccessor::value_type ImageValueType;
373 vigra_precondition((image.second - image.first) == (mask.second - mask.first),
"applyExposureMask: image and mask have different sizes");
374 const vigra::Diff2D imgSize = image.second - image.first;
379 ImgIter yd(image.first);
380 AlphaIter ymd(mask.first);
382 for (
int y = 0; y < imgSize.y; ++y, ++yd.y, ++ymd.y)
387 for (
int x = 0; x < imgSize.x; ++x, ++xd.x, ++xmd.x)
391 if (minVal < LowerLimit || maxVal > UpperLimit)
406 template<
typename PIXEL>
409 if (img1 > 0 && img2 > 0) {
430 template <
class F1,
class F2>
450 template <
class T1,
class T2>
453 return f1(
f2(v1,v2));
457 template <
class T1,
class T2,
class T3>
460 return f1(
f2(v1,v2,v3));
472 template<
typename PIXEL>
494 template <
class SrcImageIterator,
class SrcAccessor>
495 void circularCrop(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> img,
498 vigra::Diff2D imgSize = img.second - img.first;
499 double r2 = radius*radius;
502 SrcImageIterator yd(img.first);
504 for(
int y=0; y < imgSize.y; ++y, ++yd.y)
507 SrcImageIterator xd(yd);
508 for(
int x=0; x < imgSize.x; ++x, ++xd.x)
510 double dx = x-middle.
x;
511 double dy = y-middle.
y;
512 if (dx*dx+dy*dy > r2) {
536 template <
class T2,
class A>
550 typename vigra::NumericTraits<T>::RealPromote
557 typename vigra::NumericTraits<T>::RealPromote
565 template <
class DestValueType>
583 template <
class SrcValueType>
586 return vigra::NumericTraits<result_type>::fromRealPromote(
scale_ * (vigra::NumericTraits<SrcValueType>::toRealPromote(s) +
offset_));
615 typedef vigra::NumericTraits<vigra::UInt8> DestTraits;
619 template <
class T,
unsigned int R,
unsigned int G,
unsigned int B>
620 vigra::RGBValue<vigra::UInt8,0,1,2>
operator()(
const vigra::RGBValue<T,R,G,B> & v)
const
622 typedef vigra::NumericTraits< vigra::RGBValue<vigra::UInt8,0,1,2> > DestTraits;
623 typedef vigra::NumericTraits< vigra::RGBValue<T,R,G,B> > SrcTraits;
624 return DestTraits::fromRealPromote((
log10(SrcTraits::toRealPromote(v)) + (-
minv))/
scale);
629 template <
class TIn,
class TOut=vigra::UInt8>
647 typedef vigra::NumericTraits<TOut> DestTraits;
651 vigra::RGBValue<TOut>
operator()(
const vigra::RGBValue<TIn> & v)
const
653 typedef vigra::NumericTraits< vigra::RGBValue<TOut> > DestTraits;
654 typedef vigra::NumericTraits< vigra::RGBValue<TIn> > SrcTraits;
663 vigra::UInt8 lut[65536];
668 for (
int i=0; i<65536; i++) {
678 vigra::RGBValue<vigra::UInt8>
operator()(
const vigra::RGBValue<vigra::UInt16> & v)
const
680 return vigra::RGBValue<vigra::UInt8>(lut[v[0]], lut[v[1]], lut[v[2]]);
684 template <
class SrcIterator,
class SrcAccessor,
class DestIterator,
class DestAccessor,
class T>
685 void applyMapping(vigra::triple<SrcIterator, SrcIterator, SrcAccessor> img,
686 vigra::pair<DestIterator, DestAccessor> dest, T
min, T
max,
int mapping )
694 float offset_ = -float(min);
695 float scale_ = 255/float(max)-float(min);
718 vigra_fail(
"Unknown image mapping mode");
722 template <
class SrcImageIterator,
class SrcAccessor,
723 class DestImageIterator,
class DestAccessor,
class Functor>
726 SrcImageIterator src_lowerright, SrcAccessor sa,
727 DestImageIterator dest_upperleft, DestAccessor da,
728 Functor
const & f, vigra::Diff2D ul)
730 vigra::Diff2D destSize = src_lowerright - src_upperleft;
733 for(; src_upperleft.y < src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y, ++ul.y)
735 typename SrcImageIterator::row_iterator s(src_upperleft.rowIterator());
736 typename SrcImageIterator::row_iterator send(s+ destSize.x);
737 typename DestImageIterator::row_iterator d(dest_upperleft.rowIterator());
739 for(; s != send; ++s, ++d, ++ul.x) {
740 da.set(f(sa(s), ul), d);
745 template <
class SrcImageIterator,
class SrcAccessor,
746 class DestImageIterator,
class DestAccessor,
class Functor>
749 vigra::pair<DestImageIterator, DestAccessor> dest,
750 Functor
const & f, vigra::Diff2D ul)
756 template <
class ImageType>
759 typedef vigra::NumericTraits<typename ImageType::PixelType> DestTraits;
762 const std::string pixelType = vigra::TypeAsString<typename DestTraits::ValueType>::result();
764 if (pixelType ==
"FLOAT" || pixelType ==
"DOUBLE")
766 vigra::FindMinMax<typename ImageType::PixelType> minmax;
772 if (minVal != 0 || maxVal != 255)
780 #endif // VIGRA_EXT_UTILS_H
void transformImageSpatial(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestAccessor da, Functor const &f, vigra::Diff2D ul)
vigra::RGBValue< vigra::UInt8 > operator()(const vigra::RGBValue< vigra::UInt16 > &v) const
vigra::RGBValue< V1, R, G, B > & operator+=(vigra::RGBValue< V1, R, G, B > &l, V2 const &r)
add a scalar to all components
double getMaxValForPixelType(const std::string &v)
V getMaxComponent(vigra::RGBValue< V > const &v)
get the maximum component of a vector (also works for single pixel types...)
PointPairT(short img1, VALUE val1, const hugin_utils::FDiff2D &p1, float r1, short img2, VALUE val2, const hugin_utils::FDiff2D &p2, float r2)
void transformImage(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, vigra::Diff2D destUL, TRANSFORM &transform, PixelTransform &pixelTransform, bool warparound, Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
Transform an image into the panorama.
unsigned char operator()(T v) const
T operator()(const T &a) const
VALUETYPE argument_type
the functor's argument type
LUT_TRAITS(unsigned char, 0, UCHAR_MAX)
misc math function & classes used by other parts of the program
static const double A(-0.75)
result_type operator()(T1 const &v) const
ApplyLogFunctor(float min_, float max_)
vigra::UInt8 operator()(vigra::UInt16 v) const
count pixels that are > 0 in a single image
vigra::PromoteTraits< vigra::RGBValue< V1, R, G, B >, V2 >::Promote operator+(vigra::RGBValue< V1, R, G, B > const &r1, V2 const &r2)
add a scalar to all components
void applyMapping(vigra::triple< SrcIterator, SrcIterator, SrcAccessor > img, vigra::pair< DestIterator, DestAccessor > dest, T min, T max, int mapping)
NestFunctor(const F1 &fu1, const F2 &fu2)
VALUETYPE result_type
the functor's result type
A hdrWeight(T2 v, A a) const
vigra::RGBValue< T, RIDX, GIDX, BIDX > log10(vigra::RGBValue< T, RIDX, GIDX, BIDX > const &v)
component-wise logarithm
vigra::NumericTraits< T >::RealPromote normalizeValue(T v, vigra::VigraTrueType)
normalize a pixel to 0..1 Only has an effect on integer pixel types
void operator()(argument_type const &v)
update min and max
result_type operator()(T1 const &v1, T2 const &v2, T3 const &v3) const
if F2 takes 3 arguments
unsigned int count
the number of values processed so far
#define VT_TRAITS_VEC(T1)
vigra::FRGBImage ImageType
float pow(float a, double b)
void applyExposureClipMask(vigra::triple< ImgIter, ImgIter, ImgAccessor > image, vigra::triple< AlphaIter, AlphaIter, AlphaAccessor > mask, double lowerLimit, double upperLimit)
void operator()(vigra::RGBValue< VALUETYPE > const &v)
update min and max with components of RGBValue<VALUETYPE>
void operator()(PIXEL const &img1)
PointPairT< float > PointPair
vigra::pair< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImage(ROIImage< Image, Alpha > &img)
functor to combine two functors: result = f1( f2(v) )
vigra::triple< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImageRange(const ROIImage< Image, Mask > &img)
helper function for ROIImages
VALUETYPE min
the current min
ApplyGammaFunctor(TIn min_, TIn max_, float gamma_)
vigra::RGBValue< T, RIDX, GIDX, BIDX > log(vigra::RGBValue< T, RIDX, GIDX, BIDX > const &v)
component-wise logarithm
TOut operator()(TIn v) const
vigra::RGBValue< TOut > operator()(const vigra::RGBValue< TIn > &v) const
VALUETYPE max
the current max
void reset()
(re-)init functor (clear min, max)
ApplyGammaFunctor(vigra::UInt16 min, vigra::UInt16 max, float gamma)
FindComponentsMinMax()
init min and max
T1::value_type value_type
F1::result_type result_type
the functor's second argument type
vigra::RGBValue< vigra::UInt8, 0, 1, 2 > operator()(const vigra::RGBValue< T, R, G, B > &v) const
V getMinComponent(vigra::RGBValue< V > const &v)
get the maximum component of a vector (also works for single pixel types...)
T2 operator()(const T2 &a, const hugin_utils::FDiff2D &p) const
void ConvertTo8Bit(ImageType &image)
converts to given image to fit into 0..255
count pixels that are > 0 in both images
void operator()(PIXEL const &img1, PIXEL const &img2)
result_type operator()(T1 const &v1, T2 const &v2) const
if F2 takes 2 arguments
PointPairT< vigra::RGBValue< float > > PointPairRGB
void circularCrop(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > img, hugin_utils::FDiff2D middle, double radius)
Apply a circular crop to img.