|
6 | 6 | #include "CalibrationHarp.hpp"
|
7 | 7 |
|
8 | 8 | #define HAHAHA 5
|
9 |
| -#define UNDIST 1 |
10 |
| - |
11 |
| -struct Undistort |
12 |
| -{ |
13 |
| - static const int N = 20, NUM_INTRINSIC = 3; |
14 |
| - std::vector<std::vector<cv::Point2d>> points, points_undistort; |
15 |
| - double cx, cy;// center of distortion |
16 |
| - double f;// focal length |
17 |
| - |
18 |
| - int nk, iter; |
19 |
| - double klist[N] = { 1, };// list of coefficients for distortion correction polynomial and cx, cy, f |
20 |
| - double hessian[N][N], grad[N]; |
21 |
| - double lambda = 0; |
22 |
| - double fxy[N][N], fx[N], fx_[N], fy[N], dk[N]; |
23 |
| - |
24 |
| - Undistort(std::vector<std::vector<cv::Point2d>> points_, double cx_, double cy_, double f, int nk_ = 6, int iter_ = 500) |
25 |
| - :points(points_), points_undistort(points_), cx(cx_), cy(cy_), nk(nk_), iter(iter_) |
26 |
| - { |
27 |
| - klist[nk++] = cx, klist[nk++] = cy, klist[nk++] = f; |
28 |
| - calcGrad(); |
29 |
| - calcHessian(); |
30 |
| - for (int i = 0; i < nk; ++i) |
31 |
| - { |
32 |
| - lambda += hessian[i][i]; |
33 |
| - } |
34 |
| - lambda *= 0.001; |
35 |
| - } |
36 |
| - |
37 |
| - // Compute the least squares fitting error for minimum current undistorted result for each line. |
38 |
| - double calcErr() |
39 |
| - { |
40 |
| - cx = klist[nk - NUM_INTRINSIC]; |
41 |
| - cy = klist[nk - NUM_INTRINSIC + 1]; |
42 |
| - f = klist[nk - NUM_INTRINSIC + 2]; |
43 |
| - |
44 |
| - double res = 0, r, rk, fr; |
45 |
| - double a, b, c, sin, cos, sx, sy, alpha, beta; |
46 |
| - double xd, yd; |
47 |
| - int nl = points.size(), np; |
48 |
| - for (int i = 0; i < nl; ++i) |
49 |
| - { |
50 |
| - auto& line = points[i]; |
51 |
| - auto& line_undistort = points_undistort[i]; |
52 |
| - np = line.size(); |
53 |
| - if (np <= 2) continue; |
54 |
| - |
55 |
| - for (int i = 0; i < np; ++i) |
56 |
| - { |
57 |
| - xd = line[i].x, yd = line[i].y; |
58 |
| - r = (xd - cx) * (xd - cx) + (yd - cy) * (yd - cy), r /= (f * f); |
59 |
| - rk = r, fr = 1; |
60 |
| - for (int j = 1; j < nk - NUM_INTRINSIC; ++j) fr += klist[j] * rk, rk *= r; |
61 |
| - line_undistort[i].x = fr * (xd - cx) + cx; |
62 |
| - line_undistort[i].y = fr * (yd - cy) + cy; |
63 |
| - } |
64 |
| - |
65 |
| - a = b = c = sx = sy = 0; |
66 |
| - for (auto p : line_undistort) |
67 |
| - { |
68 |
| - a += p.x * p.x, b += p.x * p.y, c += p.y * p.y; |
69 |
| - sx += p.x, sy += p.y; |
70 |
| - } |
71 |
| - a -= sx * sx / np, b -= sx * sy / np, c -= sy * sy / np; |
72 |
| - alpha = a - c, beta = alpha / (2 * sqrt(alpha * alpha + 4 * b * b)); |
73 |
| - sin = sqrt(0.5 - beta); |
74 |
| - cos = sqrt(0.5 + beta); |
75 |
| - res += a * sin * sin - 2 * std::abs(b) * sin * cos + c * cos * cos; |
76 |
| - } |
77 |
| - return res; |
78 |
| - } |
79 |
| - |
80 |
| - void calcGrad() |
81 |
| - { |
82 |
| - double f0 = calcErr(); |
83 |
| - for (int i = 0; i < nk; ++i) |
84 |
| - { |
85 |
| - dk[i] = std::max(klist[i] * 1e-4, 1e-6); |
86 |
| - klist[i] += dk[i], fx[i] = calcErr(); |
87 |
| - klist[i] -= 2 * dk[i], fx_[i] = calcErr(); |
88 |
| - klist[i] += dk[i]; |
89 |
| - grad[i] = (fx[i] - f0) / dk[i]; |
90 |
| - } |
91 |
| - for (int i = 0; i < nk; ++i) |
92 |
| - { |
93 |
| - for (int j = 0; j < nk; ++j) |
94 |
| - { |
95 |
| - klist[i] += dk[i], klist[j] += dk[j]; |
96 |
| - fxy[i][j] = calcErr(); |
97 |
| - klist[i] -= dk[i], klist[j] -= dk[j]; |
98 |
| - } |
99 |
| - } |
100 |
| - } |
101 |
| - |
102 |
| - void calcHessian() |
103 |
| - { |
104 |
| - double f0 = calcErr(); |
105 |
| - for (int i = 0; i < nk; ++i) |
106 |
| - { |
107 |
| - for (int j = 0; j < nk; ++j) |
108 |
| - { |
109 |
| - if (i > j) hessian[i][j] = hessian[j][i]; |
110 |
| - else if (i == j) |
111 |
| - { |
112 |
| - hessian[i][i] = (fx[i] + fx_[i] - 2 * f0) / dk[i]; |
113 |
| - } |
114 |
| - else |
115 |
| - { |
116 |
| - hessian[i][j] = (fxy[i][j] + f0 - fx[i] - fx[j]) / (dk[i] * dk[j]); |
117 |
| - } |
118 |
| - } |
119 |
| - } |
120 |
| - } |
121 |
| - |
122 |
| - void proc() |
123 |
| - { |
124 |
| - while (iter--) |
125 |
| - { |
126 |
| - double errPre = calcErr(); |
127 |
| - calcGrad(); |
128 |
| - calcHessian(); |
129 |
| - for (int i = 0; i < nk; ++i) hessian[i][i] += lambda; |
130 |
| - |
131 |
| - cv::Mat A(nk, nk, CV_64FC1); |
132 |
| - for (int i = 0; i < nk; ++i) |
133 |
| - { |
134 |
| - for (int j = 0; j < nk; ++j) |
135 |
| - { |
136 |
| - A.at<double>(i, j) = hessian[i][j]; |
137 |
| - } |
138 |
| - } |
139 |
| - cv::invert(A, A); |
140 |
| - cv::Mat b(nk, 1, CV_64FC1, grad); |
141 |
| - cv::Mat x = -A * b; |
142 |
| - for (int i = 0; i < nk; ++i) |
143 |
| - { |
144 |
| - klist[i] += x.at<double>(i); |
145 |
| - } |
146 |
| - if (calcErr() > errPre) |
147 |
| - { |
148 |
| - for (int i = 0; i < nk; ++i) |
149 |
| - { |
150 |
| - klist[i] -= x.at<double>(i); |
151 |
| - } |
152 |
| - lambda *= 10; |
153 |
| - } |
154 |
| - else lambda = std::max(lambda / 10, 1e-16); |
155 |
| - |
156 |
| -#if 0 |
157 |
| - printf("cx:%f, cy:%f, error:%f, lambda:%f\n", cx, cy, errPre, lambda); |
158 |
| -#endif |
159 |
| - } |
160 |
| - } |
161 |
| -}; |
162 |
| - |
163 | 9 |
|
164 | 10 | CalibrationHarp::CalibrationHarp() { return; }
|
165 | 11 |
|
@@ -320,44 +166,6 @@ bool CalibrationHarp::interpolate_edge_points(
|
320 | 166 | }
|
321 | 167 | }
|
322 | 168 |
|
323 |
| -#if UNDIST |
324 |
| - { |
325 |
| - std::vector<std::vector<cv::Point2d>> points; |
326 |
| - std::vector<std::vector<Point2i>> points_undistort; |
327 |
| - for (auto& v : subsampled_edge_points) |
328 |
| - { |
329 |
| - std::vector<cv::Point2d> t; |
330 |
| - for (auto& p : v) |
331 |
| - { |
332 |
| - t.push_back(cv::Point2d(p.x, p.y)); |
333 |
| - } |
334 |
| - points.push_back(t); |
335 |
| - } |
336 |
| - Undistort udt(points, image.cols / 2, image.rows / 2, image.cols / 2); |
337 |
| - udt.proc(); |
338 |
| - for (auto& v : udt.points_undistort) |
339 |
| - { |
340 |
| - std::vector<Point2i> t; |
341 |
| - for (auto& p : v) |
342 |
| - { |
343 |
| - t.push_back(Point2i(p.x, p.y)); |
344 |
| - } |
345 |
| - points_undistort.push_back(t); |
346 |
| - } |
347 |
| - |
348 |
| - calculate_error(points_undistort, d, d_max, d_c_median); |
349 |
| - std::cout << "after undistort:" << std::endl; |
350 |
| - std::cout << "d: " << d << " pixels" << std::endl; |
351 |
| - std::cout << "d_max: " << d_max << " pixels" << std::endl; |
352 |
| - |
353 |
| - cv::Mat show = image.clone(); |
354 |
| - line_detector.drawSegments(show, points_undistort); |
355 |
| - cv::resize(show, show, cv::Size(800, 600)); |
356 |
| - cv::imshow("undistort", show); |
357 |
| - cv::waitKey(); |
358 |
| - } |
359 |
| -#endif |
360 |
| - |
361 | 169 | return true;
|
362 | 170 | }
|
363 | 171 |
|
|
0 commit comments