forked from sthalik/headtracker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathransac.cpp
128 lines (99 loc) · 3.85 KB
/
ransac.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "ht-api.h"
#include "ht-internal.h"
using namespace std;
using namespace cv;
bool ht_ransac_best_indices(headtracker_t& ctx, float& mean_error, Mat& rvec_, Mat& tvec_) {
Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
intrinsics.at<float> (0, 0) = ctx.focal_length_w;
intrinsics.at<float> (1, 1) = ctx.focal_length_h;
intrinsics.at<float> (0, 2) = ctx.grayscale.cols/2;
intrinsics.at<float> (1, 2) = ctx.grayscale.rows/2;
Mat dist_coeffs = Mat::zeros(5, 1, CV_32FC1);
Mat rvec = Mat::zeros(3, 1, CV_64FC1);
Mat tvec = Mat::zeros(3, 1, CV_64FC1);
for (int i = 0; i < 5; i++)
dist_coeffs.at<float>(i) = ctx.config.dist_coeffs[i];
rvec.at<double> (0, 0) = 1.0;
tvec.at<double> (0, 0) = 1.0;
tvec.at<double> (1, 0) = 1.0;
vector<Point3f> object_points;
vector<Point2f> image_points;
for (int i = 0; i < ctx.config.max_keypoints; i++) {
if (ctx.keypoints[i].idx == -1)
continue;
object_points.push_back(ctx.keypoint_uv[i]);
image_points.push_back(ctx.keypoints[i].position);
}
if (object_points.size() >= 15)
{
if (ctx.has_pose)
{
rvec = ctx.rvec.clone();
tvec = ctx.tvec.clone();
}
solvePnPRansac(object_points,
image_points,
intrinsics,
dist_coeffs,
rvec,
tvec,
ctx.has_pose,
ctx.config.ransac_num_iters,
ctx.config.ransac_max_inlier_error * ctx.zoom_ratio,
object_points.size() * ctx.config.ransac_min_features,
noArray(),
HT_PNP_TYPE);
vector<Point2f> projected;
vector<Point3f> all_points;
for (int i = 0; i < ctx.config.max_keypoints; i++)
{
if (ctx.keypoints[i].idx == -1)
continue;
all_points.push_back(ctx.keypoint_uv[i]);
}
projectPoints(all_points, rvec, tvec, intrinsics, dist_coeffs, projected);
mean_error = 0;
float max_dist = ctx.config.ransac_max_reprojection_error * ctx.zoom_ratio;
max_dist *= max_dist;
int inliers_count = 0;
std::vector<Point3f> final_3d;
std::vector<Point2f> final_2d;
for (int i = 0, j = 0; i < ctx.config.max_keypoints; i++)
{
if (ctx.keypoints[i].idx == -1)
continue;
float dist = ht_distance2d_squared(ctx.keypoints[i].position, projected[j++]);
if (dist > max_dist)
{
ctx.keypoints[i].idx = -1;
continue;
}
final_3d.push_back(ctx.keypoint_uv[i]);
final_2d.push_back(ctx.keypoints[i].position);
mean_error += dist;
inliers_count++;
}
if (inliers_count >= 10)
{
mean_error = sqrt(mean_error / inliers_count);
Mat rvec = Mat::zeros(3, 1, CV_64FC1);
Mat tvec = Mat::zeros(3, 1, CV_64FC1);
rvec.at<double> (0, 0) = 1.0;
tvec.at<double> (0, 0) = 1.0;
tvec.at<double> (1, 0) = 1.0;
if (ctx.has_pose)
{
rvec = ctx.rvec.clone();
tvec = ctx.tvec.clone();
}
solvePnP(final_3d, final_2d, intrinsics, dist_coeffs, rvec, tvec, ctx.has_pose, HT_PNP_TYPE);
rvec_ = rvec.clone();
tvec_ = tvec.clone();
return true;
}
}
if (ctx.config.debug)
fprintf(stderr, "ransac failed maxerr=%f zoom-ratio=%f cur=%d\n",
ctx.config.ransac_max_inlier_error, ctx.zoom_ratio, (int) object_points.size());
return false;
}