forked from Celebrandil/CudaSift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
geomFuncs.cpp
72 lines (71 loc) · 2.47 KB
/
geomFuncs.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <cmath>
#include <opencv2/core/core.hpp>
#include "cudaSift.h"
int ImproveHomography(SiftData &data, float *homography, int numLoops, float minScore, float maxAmbiguity, float thresh)
{
#ifdef MANAGEDMEM
SiftPoint *mpts = data.m_data;
#else
if (data.h_data==NULL)
return 0;
SiftPoint *mpts = data.h_data;
#endif
float limit = thresh*thresh;
int numPts = data.numPts;
cv::Mat M(8, 8, CV_64FC1);
cv::Mat A(8, 1, CV_64FC1), X(8, 1, CV_64FC1);
double Y[8];
for (int i=0;i<8;i++)
A.at<double>(i, 0) = homography[i] / homography[8];
for (int loop=0;loop<numLoops;loop++) {
M = cv::Scalar(0.0);
X = cv::Scalar(0.0);
for (int i=0;i<numPts;i++) {
SiftPoint &pt = mpts[i];
if (pt.score<minScore || pt.ambiguity>maxAmbiguity)
continue;
float den = A.at<double>(6)*pt.xpos + A.at<double>(7)*pt.ypos + 1.0f;
float dx = (A.at<double>(0)*pt.xpos + A.at<double>(1)*pt.ypos + A.at<double>(2)) / den - pt.match_xpos;
float dy = (A.at<double>(3)*pt.xpos + A.at<double>(4)*pt.ypos + A.at<double>(5)) / den - pt.match_ypos;
float err = dx*dx + dy*dy;
float wei = (err<limit ? 1.0f : 0.0f); //limit / (err + limit);
Y[0] = pt.xpos;
Y[1] = pt.ypos;
Y[2] = 1.0;
Y[3] = Y[4] = Y[5] = 0.0;
Y[6] = - pt.xpos * pt.match_xpos;
Y[7] = - pt.ypos * pt.match_xpos;
for (int c=0;c<8;c++)
for (int r=0;r<8;r++)
M.at<double>(r,c) += (Y[c] * Y[r] * wei);
X += (cv::Mat(8,1,CV_64FC1,Y) * pt.match_xpos * wei);
Y[0] = Y[1] = Y[2] = 0.0;
Y[3] = pt.xpos;
Y[4] = pt.ypos;
Y[5] = 1.0;
Y[6] = - pt.xpos * pt.match_ypos;
Y[7] = - pt.ypos * pt.match_ypos;
for (int c=0;c<8;c++)
for (int r=0;r<8;r++)
M.at<double>(r,c) += (Y[c] * Y[r] * wei);
X += (cv::Mat(8,1,CV_64FC1,Y) * pt.match_ypos * wei);
}
cv::solve(M, X, A, cv::DECOMP_CHOLESKY);
}
int numfit = 0;
for (int i=0;i<numPts;i++) {
SiftPoint &pt = mpts[i];
float den = A.at<double>(6)*pt.xpos + A.at<double>(7)*pt.ypos + 1.0;
float dx = (A.at<double>(0)*pt.xpos + A.at<double>(1)*pt.ypos + A.at<double>(2)) / den - pt.match_xpos;
float dy = (A.at<double>(3)*pt.xpos + A.at<double>(4)*pt.ypos + A.at<double>(5)) / den - pt.match_ypos;
float err = dx*dx + dy*dy;
if (err<limit)
numfit++;
pt.match_error = sqrt(err);
}
for (int i=0;i<8;i++)
homography[i] = A.at<double>(i);
homography[8] = 1.0f;
return numfit;
}