[an error occurred while processing this directive]
Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

hugin_base/photometric/ResponseTransform.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00024 #ifndef _PHOTOMETRIC_VIGNETTING_CORRECTION_H
00025 #define _PHOTOMETRIC_VIGNETTING_CORRECTION_H
00026 
00027 #include <vector>
00028 #include <functional>
00029 #include <boost/random/mersenne_twister.hpp>
00030 
00031 #include <vigra/stdimage.hxx>
00032 #include <vigra/numerictraits.hxx>
00033 #include <vigra/array_vector.hxx>
00034 
00035 #include <hugin_math/hugin_math.h>
00036 #include <vigra_ext/lut.h>
00037 #include <vigra_ext/utils.h>
00038 #include <panodata/SrcPanoImage.h>
00039 
00040 
00041 namespace HuginBase { namespace Photometric {
00042     
00043 
00049 template <class VTIn>
00050 class ResponseTransform
00051 {
00052         
00053     public:
00055         typedef typename vigra_ext::ValueTypeTraits<VTIn>::value_type VT1;
00056         
00058         typedef std::vector<double> LUT;
00059 
00060         
00061     public:
00063         ResponseTransform();
00064         
00066         ResponseTransform(const HuginBase::SrcPanoImage & src);
00067         
00069         virtual ~ResponseTransform() {};
00070         
00071     private:
00073         void initWithSrcImg(const HuginBase::SrcPanoImage & src);
00074         
00075         
00076     public:
00078         void setFlatfield(const vigra::FImage * flat)
00079         { m_flatfield = flat; }
00080 
00082         double calcVigFactor(hugin_utils::FDiff2D d) const;
00083 
00084                 void enforceMonotonicity()
00085                 {
00086                         vigra_ext::enforceMonotonicity(m_lutR);
00087                 }
00088 
00090         typename vigra::NumericTraits<VT1>::RealPromote
00091             apply(VT1 v, const hugin_utils::FDiff2D & pos, vigra::VigraTrueType) const;
00092         
00094         typename vigra::NumericTraits<VT1>::RealPromote
00095             apply(VT1 v, const hugin_utils::FDiff2D & pos) const;
00096 
00098         typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote
00099             apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos, vigra::VigraFalseType) const;
00100         
00102         typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote
00103             apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos) const;
00104         
00105         
00107         template <class T>
00108         typename vigra::NumericTraits<T>::RealPromote
00109             operator()(T v, const hugin_utils::FDiff2D & pos) const { return apply(v, pos); }
00110 
00111         
00112         
00113     public:
00114             
00115         LUT m_lutR;
00116         double m_radiusScale;
00117         vigra_ext::LUTFunctor<VT1, LUT> m_lutRFunc;
00118         const vigra::FImage * m_flatfield;
00119         double m_srcExposure;
00120         std::vector<double> m_RadialVigCorrCoeff;
00121         hugin_utils::FDiff2D m_RadialVigCorrCenter;
00122         int m_VigCorrMode;
00123         double m_WhiteBalanceRed;
00124         double m_WhiteBalanceBlue;
00125 
00126         HuginBase::SrcPanoImage m_src;
00127 };
00128 
00129 
00135 template <class VTIn, class VTOut>
00136 class InvResponseTransform : public ResponseTransform<VTIn>
00137 {
00138 
00139         typedef ResponseTransform<VTIn> Base;
00140      
00141     public:
00142         typedef typename vigra_ext::ValueTypeTraits<VTIn>::value_type VT1;
00143         typedef typename vigra::NumericTraits<VT1>::RealPromote VTInCompReal;
00144         typedef typename vigra_ext::ValueTypeTraits<VTOut>::value_type dest_type;
00145 
00146         typedef std::vector<double> LUT;
00147         typedef std::vector<dest_type> LUTD;
00148 
00149 
00150     public:
00152         InvResponseTransform();
00153 
00155         InvResponseTransform(const HuginBase::SrcPanoImage & src);
00156         
00158         virtual ~InvResponseTransform() {};
00159         
00160     private:
00162         void init(const HuginBase::SrcPanoImage & src);
00163 
00164         
00165     public:
00167         void setHDROutput(bool hdrMode=true);
00168         
00170         void setOutput(double destExposure, const LUTD & destLut, double scale);
00171         
00172                 void enforceMonotonicity()
00173                 {
00174                     if (Base::m_lutR.size()) {
00175                                 vigra_ext::enforceMonotonicity(Base::m_lutR);
00176                         // todo: invert lut, instead of using this functor?
00177                         m_lutRInvFunc = vigra_ext::InvLUTFunctor<VT1, LUT>(Base::m_lutR);
00178                         }
00179                 }
00180 
00187         double dither(const double &v) const;
00188         
00190         typename vigra::NumericTraits<dest_type>::RealPromote
00191             apply(VT1 v, const hugin_utils::FDiff2D & pos, vigra::VigraTrueType) const;
00192         
00194         typename vigra::NumericTraits<dest_type>::RealPromote
00195             apply(VT1 v, const hugin_utils::FDiff2D & pos) const;
00196         
00198         typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote
00199             apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos, vigra::VigraFalseType) const;
00200         
00202         typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote
00203             apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos) const;
00204         
00205         
00207         template <class T>
00208         typename vigra::NumericTraits<T>::RealPromote 
00209             operator()(T v, const hugin_utils::FDiff2D & pos) const
00210         {
00211             return apply(v, pos);
00212         }
00213         
00215         template <class T, class A>
00216         A hdrWeight(T v, A a) const
00217         {
00218             if (m_hdrMode && a > 0) {
00219                 return vigra::NumericTraits<A>::fromRealPromote(vigra_ext::getMaxComponent(v)/(double)vigra_ext::LUTTraits<T>::max()*vigra_ext::LUTTraits<A>::max());
00220             } else {
00221                 return a;
00222             }
00223         }
00224         
00225         void emitGLSL(std::ostringstream& oss, std::vector<double>& invLut, std::vector<double>& destLut) const;
00226 
00227     protected: // needs be public?
00228         //LUT m_lutRInv;
00229         vigra_ext::InvLUTFunctor<VT1, LUT> m_lutRInvFunc;
00230         LUTD m_destLut;
00231         vigra_ext::LUTFunctor<VTInCompReal, LUTD> m_destLutFunc;
00232         double m_destExposure;
00233         bool m_hdrMode;
00234         double m_intScale;
00235         
00236     private:
00237         boost::mt19937 Twister;
00238 };
00239 
00240 
00241 }} // namespace
00242 
00243 
00244 
00245 
00246 // templated implementation ----------------------------------------------------
00247 
00248 
00249 namespace HuginBase { namespace Photometric {
00250 
00251 
00252 template <class VTIn>
00253 ResponseTransform<VTIn>::ResponseTransform()
00254 {
00255     m_radiusScale=0;
00256     m_flatfield = 0;
00257 }
00258 
00259 template <class VTIn>
00260 ResponseTransform<VTIn>::ResponseTransform(const HuginBase::SrcPanoImage & src)
00261 {
00262     initWithSrcImg(src);
00263 }
00264 
00265 
00266 template <class VTIn>
00267 void ResponseTransform<VTIn>::initWithSrcImg(const HuginBase::SrcPanoImage & src)
00268 {
00269 //        DEBUG_DEBUG(" " << src.getFilename() << ": resp type:" <<   src.getResponseType() << " expo: " << src.getExposure());
00270     m_flatfield = 0;
00271     m_src = src;
00272     m_radiusScale = 1.0/sqrt(m_src.getSize().x/2.0*m_src.getSize().x/2.0 + m_src.getSize().y/2.0*m_src.getSize().y/2.0);
00273     m_srcExposure = m_src.getExposure();
00274     //save some variables, direct access is slower since merging of layout mode
00275     m_RadialVigCorrCoeff = m_src.getRadialVigCorrCoeff();
00276     m_RadialVigCorrCenter = m_src.getRadialVigCorrCenter();
00277     m_VigCorrMode = m_src.getVigCorrMode();
00278     m_WhiteBalanceRed = m_src.getWhiteBalanceRed();
00279     m_WhiteBalanceBlue = m_src.getWhiteBalanceBlue();
00280 
00281     // build response function lookup table, if required
00282     if (m_src.getResponseType() != HuginBase::SrcPanoImage::RESPONSE_LINEAR) {
00283         // scale lut to right byte size..
00284         double lutLenD = vigra_ext::LUTTraits<VT1>::max();
00285         // maximum lut size: 10 bits. Should be enought for most purposes.
00286         // and fit into the L1 cache.
00287         size_t lutLen=0;
00288         if (lutLenD == 1.0 || (lutLenD > ((1<<10)-1))) {
00289             lutLen = (1<<10);
00290         } else {
00291             lutLen = size_t(lutLenD) + 1;
00292         }
00293         switch (m_src.getResponseType()) 
00294         {
00295             case HuginBase::SrcPanoImage::RESPONSE_EMOR:
00296                 {
00297                 if (lutLen == 1<<10) {
00298                     vigra_ext::EMoR::createEMoRLUT(m_src.getEMoRParams(), m_lutR);
00299                 } else {
00300                     // resize lut, if size doesn't fit
00301                     LUT tmp;
00302                     vigra_ext::EMoR::createEMoRLUT(m_src.getEMoRParams(), tmp);
00303                     m_lutR.resize(lutLen);
00304                     vigra_ext::resizeLUT(tmp, m_lutR);
00305                 }
00306                 }
00307                 break;
00308             case HuginBase::SrcPanoImage::RESPONSE_GAMMA:
00309                 m_lutR.resize(lutLen);
00310                 vigra_ext::createGammaLUT(m_src.getGamma(), m_lutR);
00311                 break;
00312             default:
00313                 // response curve is stored in src image
00314                 vigra_fail("ResponseTransform: unknown response function type");
00315                 break;
00316         }
00317         m_lutRFunc = vigra_ext::LUTFunctor<VT1, LUT>(m_lutR);
00318     }
00319 }
00320 
00321 
00322 template <class VTIn>
00323 double ResponseTransform<VTIn>::calcVigFactor(hugin_utils::FDiff2D d) const
00324 {
00325     if (m_VigCorrMode & HuginBase::SrcPanoImage::VIGCORR_RADIAL) {
00326         d = d - m_RadialVigCorrCenter;
00327         // scale according to 
00328         d *= m_radiusScale;
00329         double vig = m_RadialVigCorrCoeff[0];
00330         double r2 = d.x*d.x + d.y*d.y;
00331         double r = r2;
00332         for (unsigned int i = 1; i < 4; i++) {
00333             vig += m_RadialVigCorrCoeff[i] * r;
00334             r *= r2;
00335         }
00336         return vig;
00337     } else if (m_VigCorrMode & HuginBase::SrcPanoImage::VIGCORR_FLATFIELD) {
00338         // TODO: implement flatfield
00339         if (m_flatfield) {
00340             int x = std::min(std::max(hugin_utils::roundi(d.x),0), m_flatfield->width()-1);;
00341             int y = std::min(std::max(hugin_utils::roundi(d.y),0), m_flatfield->height()-1);;
00342             return (*m_flatfield)(x,y);
00343         } else {
00344             return 1;
00345         }
00346     } else {
00347         return 1;
00348     }
00349 }
00350 
00351 
00352 template <class VTIn>
00353 typename vigra::NumericTraits<typename ResponseTransform<VTIn>::VT1>::RealPromote
00354 ResponseTransform<VTIn>::apply(typename ResponseTransform<VTIn>::VT1 v, const hugin_utils::FDiff2D & pos, vigra::VigraTrueType) const
00355 {
00356     typename vigra::NumericTraits<VT1>::RealPromote ret = v;
00357     // first, apply vignetting
00358 
00359     ret = ret*calcVigFactor(pos)*m_srcExposure;
00360     if (m_lutR.size()) {
00361         return m_lutRFunc(ret);
00362     } else {
00363         return ret;
00364     }
00365 }
00366 
00367 template <class VTIn>
00368 typename vigra::NumericTraits<vigra::RGBValue<typename ResponseTransform<VTIn>::VT1> >::RealPromote
00369 ResponseTransform<VTIn>::apply(vigra::RGBValue<typename ResponseTransform<VTIn>::VT1> v, const hugin_utils::FDiff2D & pos, vigra::VigraFalseType) const
00370 {
00371     typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote ret = v;
00372     // first, apply vignetting
00373     double common = calcVigFactor(pos)*m_srcExposure;
00374     ret = ret*common;
00375     // apply white balance factors
00376     ret.red() = ret.red() * m_WhiteBalanceRed;
00377     ret.blue() = ret.blue() * m_WhiteBalanceBlue;
00378     // apply response curve
00379     if (m_lutR.size()) {
00380         return m_lutRFunc(ret);
00381     } else {
00382         return ret;
00383     }
00384 }
00385 
00386 template <class VTIn>
00387 typename vigra::NumericTraits<typename ResponseTransform<VTIn>::VT1>::RealPromote
00388 ResponseTransform<VTIn>::apply(typename ResponseTransform<VTIn>::VT1 v, const hugin_utils::FDiff2D & pos) const
00389 {
00390     typedef typename vigra::NumericTraits<VT1>::isScalar is_scalar;
00391     return apply(v, pos, is_scalar());
00392 }
00393 
00394 template <class VTIn>
00395 typename vigra::NumericTraits<vigra::RGBValue<typename ResponseTransform<VTIn>::VT1> >::RealPromote
00396 ResponseTransform<VTIn>::apply(vigra::RGBValue<typename ResponseTransform<VTIn>::VT1> v, const hugin_utils::FDiff2D & pos) const
00397 {
00398     typedef typename vigra::NumericTraits<vigra::RGBValue<VT1> >::isScalar is_scalar;
00399     return apply(v, pos, is_scalar());
00400 }
00401 
00402 template <class VTIn, class VTOut>
00403 InvResponseTransform<VTIn,VTOut>::InvResponseTransform()
00404 {
00405     m_destExposure = 1.0;
00406     m_hdrMode = false;
00407     m_intScale = 1;
00408 }
00409 
00410 template <class VTIn, class VTOut>
00411 InvResponseTransform<VTIn,VTOut>::InvResponseTransform(const HuginBase::SrcPanoImage & src)
00412 : Base(src), m_hdrMode(false)
00413 {
00414     m_destExposure = 1.0;
00415     m_intScale = 1;
00416     if (Base::m_lutR.size()) {
00417         // todo: invert lut, instead of using this functor?
00418         m_lutRInvFunc = vigra_ext::InvLUTFunctor<VT1, LUT>(Base::m_lutR);
00419     }
00420 }
00421 
00422 template <class VTIn, class VTOut>
00423 void InvResponseTransform<VTIn,VTOut>::init(const HuginBase::SrcPanoImage & src)
00424 {
00425     m_destExposure = 1.0;
00426     m_intScale = 1;
00427     Base::init(src);
00428     if (Base::m_lutR.size()) {
00429         // todo: invert lut, instead of using this functor?
00430         m_lutRInvFunc = vigra_ext::InvLUTFunctor<VT1, LUT>(Base::m_lutR);
00431     }
00432 }
00433 
00434 template <class VTIn, class VTOut>
00435 void InvResponseTransform<VTIn,VTOut>::setHDROutput(bool hdrMode)
00436 {
00437     m_hdrMode = hdrMode;
00438     m_intScale = 1;
00439     m_destExposure = 1.0;
00440     m_destLut.clear();
00441 }
00442 
00443 template <class VTIn, class VTOut>
00444 void InvResponseTransform<VTIn,VTOut>::setOutput(double destExposure, const LUTD & destLut, double scale)
00445 {
00446     m_hdrMode = false;
00447     m_destLut = destLut;
00448     if (m_destLut.size() > 0) {
00449         m_destLutFunc = vigra_ext::LUTFunctor<VTInCompReal, LUTD>(m_destLut);
00450     }
00451     m_destExposure = destExposure;
00452     m_intScale = scale;
00453 }
00454 
00455 
00456 template <class VTIn, class VTOut>
00457 double InvResponseTransform<VTIn,VTOut>::dither(const double &v) const
00458 {
00459     boost::mt19937 &mt = const_cast<boost::mt19937 &>(Twister);
00460     double vFraction = v - floor(v);
00461     // Only dither values within a certain range of the rounding cutoff point.
00462     if (vFraction > 0.25 && vFraction <= 0.75) {
00463         // Generate a random number between 0 and 0.5.
00464         double random = 0.5 * (double)mt() / UINT_MAX;
00465         if ((vFraction - 0.25) >= random) {
00466             return ceil(v);
00467         } else {
00468             return floor(v);
00469         }
00470     } else {
00471         return v;
00472     }
00473 }
00474 
00475 
00476 template <class VTIn, class VTOut>
00477 typename vigra::NumericTraits<typename InvResponseTransform<VTIn,VTOut>::dest_type>::RealPromote
00478 InvResponseTransform<VTIn,VTOut>::apply(VT1 v, const hugin_utils::FDiff2D & pos, vigra::VigraTrueType) const
00479 {
00480     // inverse response
00481     typename vigra::NumericTraits<VT1>::RealPromote ret(v);
00482     if (Base::m_lutR.size()) {
00483         ret = m_lutRInvFunc(v);
00484     } else {
00485         ret /= vigra_ext::LUTTraits<VT1>::max();
00486     }
00487     // inverse vignetting and exposure
00488     ret *= m_destExposure / (Base::calcVigFactor(pos) * Base::m_srcExposure);
00489     // apply output transform if required
00490     if (m_destLut.size() > 0) {
00491         ret = m_destLutFunc(ret);
00492     }
00493     // dither all integer images
00494     if ( m_intScale > 1) {
00495         return dither(ret * m_intScale);
00496     }
00497     return ret;
00498 }
00499 
00500 
00501 template <class VTIn, class VTOut>
00502 typename vigra::NumericTraits<vigra::RGBValue<typename InvResponseTransform<VTIn,VTOut>::VT1> >::RealPromote
00503 InvResponseTransform<VTIn,VTOut>::apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos, vigra::VigraFalseType) const
00504 {
00505     typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote ret(v);
00506     if (Base::m_lutR.size()) {
00507         ret = m_lutRInvFunc(v);
00508     } else {
00509         ret /= vigra_ext::LUTTraits<VT1>::max();
00510     }
00511 
00512     // inverse vignetting and exposure
00513     ret *= m_destExposure/(Base::calcVigFactor(pos)*Base::m_srcExposure);
00514     ret.red() /= Base::m_WhiteBalanceRed;
00515     ret.blue() /= Base::m_WhiteBalanceBlue;
00516     // apply output transform if required
00517     if (m_destLut.size() > 0) {
00518         ret = m_destLutFunc(ret);
00519     }
00520     // dither 8 bit images.
00521     if (m_intScale > 1) {
00522         for (size_t i=0; i < 3; i++) {
00523             ret[i] = dither(ret[i] * m_intScale);
00524         }
00525     }
00526     return ret;
00527 }
00528 
00529 
00530 template <class VTIn, class VTOut>
00531 typename vigra::NumericTraits<typename InvResponseTransform<VTIn,VTOut>::dest_type>::RealPromote
00532 InvResponseTransform<VTIn,VTOut>::apply(VT1 v, const hugin_utils::FDiff2D & pos) const
00533 {
00534     typedef typename vigra::NumericTraits<VT1>::isScalar is_scalar;
00535     return apply(v, pos, is_scalar());
00536 }
00537 
00538 template <class VTIn, class VTOut>
00539 typename vigra::NumericTraits<vigra::RGBValue<typename InvResponseTransform<VTIn,VTOut>::VT1> >::RealPromote
00540 InvResponseTransform<VTIn,VTOut>::apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos) const
00541 {
00542     typedef typename vigra::NumericTraits<vigra::RGBValue<VT1> >::isScalar is_scalar;
00543     return apply(v, pos, is_scalar());
00544 }
00545 
00546 template <class VTIn, class VTOut>
00547 void
00548 InvResponseTransform<VTIn,VTOut>::emitGLSL(std::ostringstream& oss, std::vector<double>& invLut, std::vector<double>& destLut) const
00549 {
00550     invLut.clear();
00551     invLut.reserve(Base::m_lutR.size());
00552 
00553     for (int i = 0; i < Base::m_lutR.size(); i++) {
00554         double f = static_cast<double>(i) / (Base::m_lutR.size() - 1);
00555         double v = m_lutRInvFunc(f);
00556         invLut.push_back(v);
00557     }
00558         
00559     destLut.clear();
00560     destLut.reserve(m_destLut.size());
00561 
00562     for (typename LUTD::const_iterator lutI = m_destLut.begin(); lutI != m_destLut.end(); ++lutI) {
00563         typename LUTD::value_type entry = *lutI;
00564         destLut.push_back(entry);
00565     }
00566 
00567     double invLutSize = Base::m_lutR.size();
00568     double pixelMax = vigra_ext::LUTTraits<VT1>::max();
00569     double destLutSize = m_destLut.size();
00570 
00571     oss << "    // invLutSize = " << invLutSize << endl
00572         << "    // pixelMax = " << pixelMax << endl
00573         << "    // destLutSize = " << destLutSize << endl
00574         << "    // destExposure = " << m_destExposure << endl
00575         << "    // srcExposure = " << Base::m_srcExposure << endl
00576         << "    // whiteBalanceRed = " << Base::m_src.getWhiteBalanceRed() << endl
00577         << "    // whiteBalanceBlue = " << Base::m_src.getWhiteBalanceBlue() << endl;
00578 
00579     if (Base::m_lutR.size() > 0) {
00580         oss << "    p.rgb = p.rgb * " << (invLutSize - 1.0) << ";" << endl
00581             << "    vec2 invR = texture2DRect(InvLutTexture, vec2(p.r, 0.0)).sq;" << endl
00582             << "    vec2 invG = texture2DRect(InvLutTexture, vec2(p.g, 0.0)).sq;" << endl
00583             << "    vec2 invB = texture2DRect(InvLutTexture, vec2(p.b, 0.0)).sq;" << endl
00584             << "    vec3 invX = vec3(invR.x, invG.x, invB.x);" << endl
00585             << "    vec3 invY = vec3(invR.y, invG.y, invB.y);" << endl
00586             << "    vec3 invA = fract(p.rgb);" << endl
00587             << "    p.rgb = mix(invX, invY, invA);" << endl;
00588     }
00589 
00590     if (Base::m_src.getVigCorrMode() & HuginBase::SrcPanoImage::VIGCORR_RADIAL) {
00591         oss << "    // VigCorrMode=VIGCORR_RADIAL" << endl
00592             << "    float vig = 1.0;" << endl
00593             << "    {" << endl
00594             << "        vec2 vigCorrCenter = vec2(" << Base::m_src.getRadialVigCorrCenter().x << ", "
00595             << Base::m_src.getRadialVigCorrCenter().y << ");" << endl
00596             << "        float radiusScale=" << Base::m_radiusScale << ";" << endl
00597             << "        float radialVigCorrCoeff0 = " << Base::m_src.getRadialVigCorrCoeff()[0] << ";" << endl
00598             << "        float radialVigCorrCoeff1 = " << Base::m_src.getRadialVigCorrCoeff()[1] << ";" << endl
00599             << "        float radialVigCorrCoeff2 = " << Base::m_src.getRadialVigCorrCoeff()[2] << ";" << endl
00600             << "        float radialVigCorrCoeff3 = " << Base::m_src.getRadialVigCorrCoeff()[3] << ";" << endl
00601             << "        vec2 src = texture2DRect(CoordTexture, gl_TexCoord[0].st).sq;" << endl
00602             << "        vec2 d = src - vigCorrCenter;" << endl
00603             << "        d *= radiusScale;" << endl
00604             << "        vig = radialVigCorrCoeff0;" << endl
00605             << "        float r2 = dot(d, d);" << endl
00606             << "        float r = r2;" << endl
00607             << "        vig += radialVigCorrCoeff1 * r;" << endl
00608             << "        r *= r2;" << endl
00609             << "        vig += radialVigCorrCoeff2 * r;" << endl
00610             << "        r *= r2;" << endl
00611             << "        vig += radialVigCorrCoeff3 * r;" << endl
00612             << "    }" << endl;
00613     } else if (Base::m_src.getVigCorrMode() & HuginBase::SrcPanoImage::VIGCORR_FLATFIELD) {
00614         oss << "    // VigCorrMode=VIGCORR_FLATFIELD" << endl
00615             << "    float vig = 1.0;" << endl;
00616     } else {
00617         oss << "    // VigCorrMode=none" << endl
00618             << "    float vig = 1.0;" << endl;
00619     }
00620 
00621     oss << "    vec3 exposure_whitebalance = vec3("
00622         << (m_destExposure / (Base::m_srcExposure * Base::m_src.getWhiteBalanceRed())) << ", "
00623         << (m_destExposure / (Base::m_srcExposure)) << ", "
00624         << (m_destExposure / (Base::m_srcExposure * Base::m_src.getWhiteBalanceBlue())) << ");" << endl
00625         << "    p.rgb = (p.rgb * exposure_whitebalance) / vig;" << endl;
00626 
00627     if (m_destLut.size() > 0) {
00628         oss << "    p.rgb = p.rgb * " << (destLutSize - 1.0) << ";" << endl
00629             << "    vec2 destR = texture2DRect(DestLutTexture, vec2(p.r, 0.0)).sq;" << endl
00630             << "    vec2 destG = texture2DRect(DestLutTexture, vec2(p.g, 0.0)).sq;" << endl
00631             << "    vec2 destB = texture2DRect(DestLutTexture, vec2(p.b, 0.0)).sq;" << endl
00632             << "    vec3 destX = vec3(destR.x, destG.x, destB.x);" << endl
00633             << "    vec3 destY = vec3(destR.y, destG.y, destB.y);" << endl
00634             << "    vec3 destA = fract(p.rgb);" << endl
00635             << "    p.rgb = mix(destX, destY, destA);" << endl;
00636     }
00637 
00638     // alpha hdrWeight
00639     if (m_hdrMode) {
00640         oss << "    p.a = max(p.r, max(p.g, p.b));" << endl;
00641     }
00642 }
00643 
00644 }} // namespace
00645 
00646 #endif // _H

Generated on Mon Sep 20 01:01:27 2010 for Hugintrunk by doxygen 1.3.9.1