25 #define _USE_MATH_DEFINES
46 LUT<0, 83>
Exp1_2(exp, 0.5, -0.08);
49 std::vector<int> rings, std::vector<double>ring_radius,
50 std::vector<double>ring_gradient_width,
51 int ori_nbins,
double ori_sample_scale,
int ori_gridsize) :
52 _image(iImage), _ori_nbins(ori_nbins), _ori_sample_scale(ori_sample_scale),
53 _ori_gridsize(ori_gridsize)
59 ring_radius.push_back(0);
60 ring_gradient_width.push_back(2);
62 ring_radius.push_back(4.2);
63 ring_gradient_width.push_back(1.9);
70 ring_radius.push_back(8);
71 ring_gradient_width.push_back(3.2);
74 assert(rings.size() == ring_radius.size());
75 assert(rings.size() == ring_gradient_width.size());
98 for (
unsigned int i = 0; i < rings.size(); i++)
100 _subRegions += rings[i];
108 for (
unsigned int i = 0; i < rings.size(); i++)
113 double phioffset = i % 2 == 0 ? 0 :
M_PI / rings[i];
114 for (
int ri = 0; ri < rings[i]; ri++)
116 double phi = ri * 2 *
M_PI / rings[i] + phioffset;
117 _samples[j].
x = ring_radius[i] * cos(phi);
118 _samples[j].
y = ring_radius[i] * sin(phi);
146 if (!ioKeyPoint.
_vec)
163 int aStep = (int)(ioKeyPoint.
_scale + 0.8);
168 std::cerr <<
"ori_scale = " << 2.5 * ioKeyPoint.
_scale + 1.5 << std::endl;
169 std::cerr <<
"ori= [ ";
173 #pragma message("use LUT after parameter tuning")
175 #warning use LUT after parameter tuning
177 double coeffadd = 0.5;
180 memset(
_ori_hist, 0,
sizeof(
double)*(_ori_nbins + 2));
184 int aSY = aRY + aYIt * aStep;
187 int aSX = aRX + aXIt * aStep;
189 const int aSqDist = aXIt * aXIt + aYIt * aYIt;
190 if (aSqDist <= _ori_nbins*_ori_nbins && aWaveFilter.
checkBounds(aSX, aSY))
192 double aWavX = aWaveFilter.
getWx(aSX, aSY);
195 double aWavY = -aWaveFilter.
getWy(aSX, aSY);
196 double aWavResp = sqrt(aWavX * aWavX + aWavY * aWavY);
200 double angle = atan2(aWavY, aWavX) +
PI;
201 int bin = angle / (2 *
PI) * _ori_nbins;
205 double weight = exp(coeffmul * (aSqDist + coeffadd));
206 hist[bin] += aWavResp * weight;
209 std::cerr <<
"[ " << aSX <<
", " << aSY <<
", "
210 << aWavX <<
", " << aWavY <<
", "
211 << aWavResp <<
", " << angle <<
", " << bin <<
", "
212 << aSqDist <<
", " << aWavResp*
Exp1_2(aSqDist) <<
"], " << std::endl;
219 std::cerr <<
"]" << endl;
225 for (
int it=0; it < 1; it++)
227 double prev = hist[_ori_nbins-1];
228 double first = hist[0];
229 for (
int i=0; i < _ori_nbins-2; i++)
231 double hs = (prev + hist[i] + hist[i+1]) / 3.0;
235 hist[_ori_nbins-1] = (prev + hist[_ori_nbins-1] + first) / 3.0;
240 hist[-1] = hist[_ori_nbins - 1];
244 double aMax = hist[0];
247 std::cerr <<
"rot_hist: [ " << aMax;
252 std::cerr <<
", " << hist[i];
261 std::cerr <<
" ] " << std::endl;
264 double prev = hist[iMax - 1];
265 double curr = hist[iMax];
266 double next = hist[iMax + 1];
267 double dsub = -0.5*(next - prev) / (prev + next - 2 * curr);
268 ioKeyPoint.
_ori = (iMax + 0.5 + dsub) / _ori_nbins * 2 *
PI -
PI;
275 double prev = hist[i - 1];
276 double curr = hist[i];
277 double next = hist[i + 1];
278 if (curr > aMax && prev < curr && next < curr && i != iMax)
280 dsub = -0.5*(next - prev) / (prev + next - 2 * curr);
281 angles[nNewOri] = (i + 0.5 + dsub) / _ori_nbins * 2 *
PI -
PI;
296 std::ofstream dlog(
"descriptor_details.txt", std::ios_base::app);
302 double aX = ioKeyPoint.
_x;
303 double aY = ioKeyPoint.
_y;
304 int aS = (int)ioKeyPoint.
_scale;
307 double ori_sin = sin(ioKeyPoint.
_ori);
308 double ori_cos = cos(ioKeyPoint.
_ori);
322 double middleMean = 0;
330 double aXSample = aX + xS * ori_cos - yS * ori_sin;
331 double aYSample = aY + xS * ori_sin + yS * ori_cos;
336 int sampleArea = aIntSampleSize * aIntSampleSize;
338 if (!aWaveFilter.
checkBounds(aIntXSample, aIntYSample, aIntSampleSize))
340 ioKeyPoint.
_vec[j++] = 0;
341 ioKeyPoint.
_vec[j++] = 0;
346 ioKeyPoint.
_vec[j++] = 0;
349 dlog << xS <<
" " << yS <<
" "
350 << aIntXSample <<
" " << aIntYSample <<
" " << aIntSampleSize <<
" "
351 << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0 << std::endl;
356 double aWavX = aWaveFilter.
getWx(aIntXSample, aIntYSample, aIntSampleSize) / sampleArea;
357 double aWavY = -aWaveFilter.
getWy(aIntXSample, aIntYSample, aIntSampleSize) / sampleArea;
359 double meanGray = aWaveFilter.
getSum(aIntXSample, aIntYSample, aIntSampleSize) / sampleArea;
363 middleMean = meanGray;
370 double aWavXR = aWavX * ori_cos + aWavY * ori_sin;
371 double aWavYR = -aWavX * ori_sin + aWavY * ori_cos;
378 dlog << xS <<
" " << yS <<
" "
379 << aIntXSample <<
" " << aIntYSample <<
" " << aIntSampleSize <<
" "
380 << aWavX <<
" " << aWavY <<
" " << meanGray <<
" " << aWavXR <<
" " << aWavYR << std::endl;
384 ioKeyPoint.
_vec[j++] = aWavXR;
385 ioKeyPoint.
_vec[j++] = aWavYR;
404 ioKeyPoint.
_vec[j++] = meanGray - middleMean;
~CircularKeyPointDescriptor()
bool checkBounds(int x, int y) const
misc math function & classes used by other parts of the program
void makeDescriptor(KeyPoint &ioKeyPoint) const
void createDescriptor(KeyPoint &ioKeyPoint) const
#define PI
Header file for Khan's deghosting algorithm Copyright (C) 2009 Lukáš Jirkovský l...
LUT< 0, 83 > Exp1_2(exp, 0.5,-0.08)
double getWy(unsigned int x, unsigned int y)
const double _ori_sample_scale
double getWx(unsigned int x, unsigned int y)
CircularKeyPointDescriptor(Image &iImage, std::vector< int > rings=std::vector< int >(), std::vector< double > ring_radius=std::vector< double >(), std::vector< double > ring_gradient_width=std::vector< double >(), int ori_bins=18, double ori_sample_scale=4, int ori_gridsize=11)
double getSum(unsigned int x, unsigned int y, int scale)
void allocVector(int iSize)
int getDescriptorLength() const
int assignOrientation(KeyPoint &ioKeyPoint, double angles[4]) const
static bool Normalize(double *iVec, int iLen)