00001
00002
00003 #ifndef __SOURCETRANSFORMSPATIALSCALE_H__
00004 #define __SOURCETRANSFORMSPATIALSCALE_H__
00005
00006 #include "SourceGenerics.h"
00007 #include "SourceMemory.h"
00008 #include "SourceTransform.h"
00009 #include <math.h>
00010 #include "libInterpolatedSource.h"
00011
00012 #undef DEBUG
00013 #define DEBUG 0
00014 #include "libDebug.h"
00015
00016
00017
00018 template<class DATA, int DIMENSIONALITY, class PRECISION, class SOURCE>
00019 class SourceTransformSpatialScaleBaseOf: public SourceTransformOf<DATA,
00020 DIMENSIONALITY, PRECISION, SOURCE>
00021 {
00022 protected:
00023 typedef PixelRealGrey COEFFICIENT;
00024 typedef PointOf<DIMENSIONALITY, int> COEFFICIENTPOINT;
00025 typedef SourceMemoryOf<COEFFICIENT, DIMENSIONALITY> COEFFICIENTS;
00026
00027 mutable COEFFICIENTS* m_pcoefs;
00028
00029 public:
00030 SourceTransformSpatialScaleBaseOf() :
00031 SourceTransformOf<DATA, DIMENSIONALITY, PRECISION, SOURCE> (), m_pcoefs(
00032 NULL)
00033 {
00034 }
00035
00036 virtual ~SourceTransformSpatialScaleBaseOf()
00037 {
00038 if (Counted::AboutToDie())
00039 {
00040 ReleasePointer(m_pcoefs);
00041 }
00042 }
00043
00044 void SetCoefficients(COEFFICIENTS *pcoefs)
00045 {
00046 ReleasePointer(m_pcoefs);
00047 m_pcoefs = ClaimPointer(pcoefs);
00048 }
00049
00050 void AllocateCoefficients(const COEFFICIENTPOINT &ptSize)
00051 {
00052 ReleasePointer(m_pcoefs);
00053
00054 m_pcoefs = new COEFFICIENTS();
00055 m_pcoefs->Allocate(ptSize);
00056 }
00057
00058 void AllocateCofficients(int c)
00059 {
00060 COEFFICIENTPOINT pt(c);
00061 AllocateCofficients(pt);
00062 }
00063
00064 COEFFICIENTS* GetPCoefficients() const
00065 {
00066 return m_pcoefs;
00067 }
00068
00069 virtual String Describe() const
00070 {
00071 return (_LINE + "SourceTransformSpatialScale" + LINE_ + (_INDENT
00072 + "with coeffients: " + LINE_) + (_INDENT2 + m_pcoefs->Describe())
00073 + this->DescribeCommon());
00074 }
00075
00076 virtual void RegisterParameters(RegistryOfParameters& reg)
00077 {
00078 m_pcoefs->RegisterDataAsParameters(reg);
00079 }
00080
00081 void PrepareForAccessAction() const
00082 {
00083 ASSERTf(m_pcoefs, "Null Cofficients");
00084
00085 m_pcoefs->PrepareForAccess();
00086
00087
00088 this->m_ptSize = this->PSource()->Size();
00089 }
00090
00091 static String SerializationId()
00092 {
00093 return String("SourceTransformSpatialScale(") + DIMENSIONALITY + "D)";
00094 }
00095
00096 void SerializeSelf(Stream& st) const
00097 {
00098 ::SerializePointer(st, m_pcoefs);
00099 }
00100
00101 void DeserializeSelf(Stream& st)
00102 {
00103 ::DeserializePointer(st, m_pcoefs);
00104 }
00105 };
00106
00107
00108
00109 template<class DATA, int DIMENSIONALITY, class PRECISION, class SOURCE>
00110 class SourceTransformSpatialScaleOf: public SourceTransformSpatialScaleBaseOf<
00111 DATA, DIMENSIONALITY, PRECISION, SOURCE>
00112 {
00113 };
00114
00115
00116
00117 template<class DATA, class PRECISION, class SOURCE>
00118 class SourceTransformSpatialScaleOf<DATA, 2, PRECISION, SOURCE> : public SourceTransformSpatialScaleBaseOf<
00119 DATA, 2, PRECISION, SOURCE>
00120 {
00121 public:
00122 SOURCE_ACTUALS_2D ;
00123
00124 private:
00125 typedef PixelRealGrey COEFFICIENT;
00126 typedef PointOf<DIMENSIONALITY, int> COEFFICIENTPOINT;
00127 typedef SourceMemoryOf<COEFFICIENT, DIMENSIONALITY>* COEFFICIENTS;
00128
00129 public:
00130 void Get(DATA& dataOut, const PRECISION& rX, const PRECISION& rY) const
00131 {
00132 ::Get(
00133 *(this->m_psource),
00134 dataOut,
00135 rX,
00136 rY
00137 );
00138
00139 int cX=this->Size().X();
00140 int cY=this->Size().Y();
00141
00142 Real rrX=Real(rX);
00143 Real rrY=Real(rY);
00144
00145 int cXCoefs=this->m_pcoefs->Size().X();
00146 int cYCoefs=this->m_pcoefs->Size().Y();
00147
00148 RANGEPROMOTION(DATA) dataT = dataOut;
00149
00150 dataT -= MidValue(DATA);
00151 for (int nXCoef=0; nXCoef<cXCoefs; nXCoef++)
00152 {
00153 for (int nYCoef=0; nYCoef<cYCoefs; nYCoef++)
00154 {
00155 COEFFICIENT coeff;
00156 this->m_pcoefs->Get(coeff,nXCoef,nYCoef);
00157
00158 Real rCosX=cos(rrX/cX * PI * nXCoef);
00159 Real rCosY=cos(rrY/cY * PI * nYCoef);
00160
00161 Real rWeight = (rCosX * rCosY) * coeff;
00162
00163 D("%d %d %d %g==%g", cXCoefs, cYCoefs, coeff,rWeight);
00164
00165 dataT += (rWeight * Range(DATA));
00166 }
00167 }
00168
00169 dataT += MidValue(DATA);
00170 dataOut = ::Bound(dataT,MinValue(DATA),MaxValue(DATA));
00171 }
00172
00173 void Set(const PRECISION& rX, const PRECISION& rY, const DATA& data)
00174 {
00175 ERROR("not implemented");
00176 }
00177 };
00178
00179
00180
00181 template<class DATA, class PRECISION, class SOURCE>
00182 class SourceTransformSpatialScaleOf<DATA, 3, PRECISION, SOURCE> : public SourceTransformSpatialScaleBaseOf<
00183 DATA, 3, PRECISION, SOURCE>
00184 {
00185 public:
00186 SOURCE_ACTUALS_3D ;
00187
00188 typedef PixelRealGrey COEFFICIENT;
00189 typedef PointOf<DIMENSIONALITY, int> COEFFICIENTPOINT;
00190 typedef SourceMemoryOf<COEFFICIENT, DIMENSIONALITY>* COEFFICIENTS;
00191
00192 public:
00193 void Get(DATA& dataOut, const PRECISION& rX, const PRECISION& rY, const PRECISION& rZ) const
00194 {
00195 ::Get(
00196 *(this->m_psource),
00197 dataOut,
00198 rX,
00199 rY,
00200 rZ
00201 );
00202
00203 PRECISION cX=this->Size().X();
00204 PRECISION cY=this->Size().Y();
00205 PRECISION cZ=this->Size().Z();
00206
00207
00208 Real rrX=Real(rX);
00209 Real rrY=Real(rY);
00210 Real rrZ=Real(rZ);
00211
00212 int cXCoefs=this->m_pcoefs->Size().X();
00213 int cYCoefs=this->m_pcoefs->Size().Y();
00214 int cZCoefs=this->m_pcoefs->Size().Z();
00215
00216
00217
00218 Real rWeightT = 0.;
00219
00220
00221 for (int nXCoef=0; nXCoef<cXCoefs; nXCoef++)
00222 {
00223 for (int nYCoef=0; nYCoef<cYCoefs; nYCoef++)
00224 {
00225 for (int nZCoef=0; nZCoef<cZCoefs; nZCoef++)
00226 {
00227 COEFFICIENT coeff;
00228 this->m_pcoefs->Get(coeff,nXCoef,nYCoef,nZCoef);
00229
00230 Real dXPhase = (nXCoef%2)?.5:0;
00231 Real dYPhase = (nYCoef%2)?.5:0;
00232 Real dZPhase = (nZCoef%2)?.5:0;
00233
00234 Real rCosX=cos((rrX/cX * nXCoef+dXPhase) * PI);
00235 Real rCosY=cos((rrY/cY * nYCoef+dYPhase) * PI);
00236 Real rCosZ=cos((rrZ/cZ * nZCoef+dZPhase) * PI);
00237
00238 Real rWeight = (rCosX * rCosY * rCosZ) * coeff;
00239
00240 rWeightT += rWeight;
00241 }
00242 }
00243 }
00244
00245
00246
00247 RANGEPROMOTION(DATA) dataT = dataOut;
00248 dataT *= exp(rWeightT);
00249 dataOut = ::Bound(dataT,RANGEPROMOTION(DATA)(MinValue(DATA)),RANGEPROMOTION(DATA)(MaxValue(DATA)));
00250 }
00251
00252 void Set(const PRECISION& rX, const PRECISION& rY, const PRECISION& rZ, const DATA& data)
00253 {
00254 ERROR("not implemented");
00255 }
00256 };
00257
00258
00259
00260
00261 MAKE_ASSISTANT(
00262 SpatialScale,
00263 SourceTransformSpatialScaleOf,
00264 {
00265 psrcOut->SetCoefficients(pcoeff);
00266 },
00267 SourceMemoryOf<PixelRealGrey, TypeOfDimensionality(SOURCE)>* pcoeff,
00268 );
00269
00270
00271
00272
00273
00274 template<int DIMENSIONALITY>
00275 SourceMemoryOf<Real, DIMENSIONALITY>* CoefficientTable(const PointOf<
00276 DIMENSIONALITY, int> &ptSize, ...)
00277 {
00278 SourceMemoryOf < Real, DIMENSIONALITY > *pi = new SourceMemoryOf<Real,
00279 DIMENSIONALITY> ();
00280 pi->Allocate(ptSize);
00281
00282 int c = ptSize.CVolume();
00283
00284 va_list listArgs;
00285
00286 va_start(listArgs, ptSize);
00287 for (int n = 0; n < c; n++)
00288 {
00289 Real pxl = va_arg(listArgs, Real);
00290 pi->SetDatum(n, pxl);
00291 }
00292 va_end(listArgs);
00293
00294 return HandoffPointer(pi);
00295 }
00296
00297 #endif // __SOURCETRANSFORMSPATIALSCALE_H__