LogPolarTransform.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef IMAGE_LOGPOLARTRANSFORM_C_DEFINED
00039 #define IMAGE_LOGPOLARTRANSFORM_C_DEFINED
00040
00041 #include "Image/LogPolarTransform.H"
00042
00043 #include "Image/MathOps.H"
00044 #include "Image/Pixels.H"
00045 #include "Image/Range.H"
00046 #include "Util/MathFunctions.H"
00047
00048 #include <algorithm>
00049 #include <cmath>
00050 #include <utility>
00051 #include <vector>
00052
00053
00054 LogPolarTransform::LogPolarTransform(const Dims& indims, const Dims& outdims,
00055 const double deg_per_pixel,
00056 const double step)
00057 :
00058 itsInDims(indims),
00059 itsOutDims(outdims)
00060 {
00061 const int w = indims.w();
00062 const int h = indims.h();
00063
00064 Range<double> xrng;
00065 Range<double> yrng;
00066
00067 const double A = 3.0;
00068 const double B_x = 1.4;
00069 const double B_y = 1.8;
00070
00071 for (int j = 0; j < h; ++j)
00072 for (int i = 0; i < w; ++i)
00073 {
00074 if (j > 0 && j < h-1 && i > 0 && i < w-1)
00075 continue;
00076
00077 const double x = (i - w / 2.0) * deg_per_pixel;
00078 const double y = (j - h / 2.0) * deg_per_pixel;
00079
00080 const double sx = (x < 0.0) ? 1.0 : -1.0;
00081
00082 const double r = sqrt(x*x + y*y);
00083 const double th = atan2(y, fabs(x));
00084
00085 const double X = sx * B_x * log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A);
00086 const double Y = -B_y * atan(r*sin(th) / (r*cos(th) + A));
00087
00088
00089
00090
00091
00092 xrng.merge(X);
00093 yrng.merge(Y);
00094 }
00095
00096 const double scale = std::min((outdims.w() - 1) / xrng.range(),
00097 (outdims.h() - 1) / yrng.range());
00098
00099 const int dw = outdims.w();
00100
00101 for (double j = 0; j < h; j += step)
00102 for (double i = 0; i < w; i += step)
00103 {
00104 const double x = (i - w / 2.0) * (120.0 / w);
00105 const double y = (j - h / 2.0) * (120.0 / h);
00106
00107 const double sx = (x < 0.0) ? 1.0 : -1.0;
00108
00109 const double r = sqrt(x*x + y*y);
00110 const double th = atan2(y, fabs(x));
00111
00112 const double X = sx * B_x * log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A);
00113 const double Y = -B_y * atan(r*sin(th) / (r*cos(th) + A));
00114
00115 if (!isFinite(X))
00116 LINFO("i,j = %f,%f", i, j);
00117
00118
00119
00120
00121
00122 const int NX = int((X - xrng.min()) * scale);
00123 const int NY = int((Y - yrng.min()) * scale);
00124
00125 itsCoords.push_back(std::make_pair(int(j)*w + int(i), NY*dw + NX));
00126 }
00127 }
00128
00129
00130 template <class T>
00131 Image<T> logPolarTransform(const LogPolarTransform& t,
00132 const Image<T>& inp, const T bkg_color)
00133 {
00134 ASSERT(inp.getDims() == t.itsInDims);
00135
00136 typedef typename promote_trait<T, double>::TP TF;
00137
00138 Image<TF> txf(t.itsOutDims, ZEROS);
00139 Image<int> counts(t.itsOutDims, ZEROS);
00140
00141 typename Image<T>::const_iterator sptr = inp.begin();
00142 typename Image<TF>::iterator txfitr = txf.beginw();
00143 Image<int>::iterator citr = counts.beginw();
00144
00145 for (size_t n = 0; n < t.itsCoords.size(); ++n)
00146 {
00147 txfitr[t.itsCoords[n].second] += TF(sptr[t.itsCoords[n].first]);
00148 citr[t.itsCoords[n].second] += 1;
00149 }
00150
00151 txfitr = txf.beginw();
00152 citr = counts.beginw();
00153
00154 Image<T> btxf(txf.getDims(), ZEROS);
00155 typename Image<T>::iterator btxfitr = btxf.beginw();
00156
00157 for (int j = 0; j < txf.getHeight(); ++j)
00158 for (int i = 0; i < txf.getWidth(); ++i)
00159 {
00160 if (*citr == 0)
00161 *btxfitr = bkg_color;
00162 else
00163 *btxfitr = T(*txfitr / double(*citr));
00164 ++btxfitr; ++txfitr; ++citr;
00165 }
00166
00167 return btxf;
00168 }
00169
00170
00171 #include "inst/Image/LogPolarTransform.I"
00172
00173
00174
00175
00176
00177
00178
00179
00180 #endif // IMAGE_LOGPOLARTRANSFORM_C_DEFINED