00001
00024 #ifndef _VIGRA_EXT_HDRUTILS_H
00025 #define _VIGRA_EXT_HDRUTILS_H
00026
00027 #include "ROIImage.h"
00028 #include "utils.h"
00029 #include "lut.h"
00030
00031
00032 namespace vigra_ext {
00033
00034
00035 template<class VALUETYPE=vigra::RGBValue<float> >
00036 class ReduceToHDRFunctor
00037 {
00038 public:
00039 typedef VALUETYPE argument_type;
00040 typedef VALUETYPE first_argument_type;
00041 typedef VALUETYPE second_argument_type;
00042 typedef VALUETYPE result_type;
00043
00044 typedef typename vigra::NumericTraits<VALUETYPE> Traits;
00045 typedef typename Traits::RealPromote real_type;
00046
00047 ReduceToHDRFunctor()
00048 {
00049 reset();
00050 }
00051
00052 void reset ()
00053 {
00054 result = vigra::NumericTraits<real_type>::zero();
00055 weight = 0;
00056
00057 maxComp = DBL_MIN;
00058 minComp = DBL_MAX;
00059 maxW= 0;
00060 minW= 1;
00061 }
00062
00063
00064 template<class T, class M>
00065 void operator() (T const &v, M const &m)
00066 {
00067
00068 double nm = m / (double)vigra_ext::LUTTraits<M>::max();
00069
00070
00071
00072
00073
00074 double w = 0.5-fabs(nm-0.5);
00075
00076 result += w*v;
00077 weight += w;
00078
00079
00080 if (nm > maxW) {
00081 maxW = w;
00082 }
00083 if ( w < minW) {
00084 minW = w;
00085 }
00086
00087 double cmax = getMaxComponent(v);
00088
00089 if (cmax > maxComp)
00090 {
00091 maxComp = cmax;
00092 maxValue = v;
00093 }
00094 if (cmax < minComp)
00095 {
00096 minComp = cmax;
00097 minValue = v;
00098 }
00099 }
00100
00102 real_type operator() () const
00103 {
00104 double eps = 1e-7;
00105
00106 if (minW > (1.0-eps) && maxW > (1.0-eps)) {
00107
00108 return minValue;
00109 } else if (minW < eps && maxW < eps) {
00110
00111 return maxValue;
00112 }
00113 if (weight > 0)
00114 return result/weight;
00115 else
00116 return result;
00117 }
00118
00119 protected:
00120 real_type result;
00121 double weight;
00122
00123 real_type maxValue;
00124 double maxComp;
00125 real_type minValue;
00126 double minComp;
00127 double maxW;
00128 double minW;
00129 };
00130
00131 #if 0
00132
00138 template <class In>
00139 double calcSigmoidHDRWeight(In val)
00140 {
00141
00142 double x = getMaxComponent(val)/((double) vigra_ext::LUTTraits<In>::max());
00143
00144
00145 x = (x-0.5)*12;
00146
00147
00148 double y = 1.0 / ( 1.0 + exp(-x));
00149
00150 double min = 1.0 / ( 1.0 + exp(+6.0));
00151 double max = 1.0 / ( 1.0 + exp(-6.0));
00152 return (y - min)/(max-min);
00153 }
00154
00155
00160 struct HDRWeightFunctor
00161 {
00162 HDRWeightFunctor()
00163 {
00164 m_lut.resize(256);
00165 std::cerr << "w = [";
00166 for (int i=0;i<256;i++) {
00167
00168 float x = (i/255.0f - 0.5f)/0.18f;
00169 vigra::UInt8 w = std::min(utils::ceili(255*exp( -x*x)), 255);
00170
00171
00172
00173 m_lut[i] = w;
00174 std::cerr << (int) w << " ";
00175 }
00176 }
00177
00178 template <class T>
00179 vigra::UInt8 operator()(vigra::RGBValue<T> rgb) const
00180 {
00181
00182
00183
00184
00185 T x = std::max(rgb[0], std::max(rgb[1], rgb[2]));
00186 return operator()(x);
00187 }
00188
00189 vigra::UInt8 operator()(float x) const
00190 {
00191 x = x*255;
00192 vigra::UInt8 i = 0;
00193 if (x> 0 || x <=255)
00194 i = (vigra::UInt8) x;
00195 return m_lut[i];
00196 }
00197
00198
00199 vigra::UInt8 operator()(vigra::UInt16 x) const
00200 {
00201 x <<= 8;
00202 return m_lut[x];
00203 }
00204
00205 vigra::UInt8 operator()(vigra::UInt8 x) const
00206 {
00207 return m_lut[x];
00208 }
00209
00210 vigra::ArrayVector<vigra::UInt8> m_lut;
00211 };
00212
00213 #endif
00214
00215
00216 }
00217 #endif //_H