Skip to content

Commit 84df75b

Browse files
committed
Merge branch 'phil-dist_model_v5'
* phil-dist_model_v5: Distortion model v5: 12-factor OpenCV distortion model.
2 parents ef346d2 + f89cc48 commit 84df75b

File tree

4 files changed

+110
-58
lines changed

4 files changed

+110
-58
lines changed

Calibration.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ bool Calibration::uncaptureAll(void)
278278

279279
void Calibration::calib(ARParam *param_out, ARdouble *err_min_out, ARdouble *err_avg_out, ARdouble *err_max_out)
280280
{
281-
calc((int)m_corners.size(), m_patternType, m_patternSize, m_chessboardSquareWidth, m_corners, m_videoWidth, m_videoHeight, param_out, err_min_out, err_avg_out, err_max_out);
281+
calc((int)m_corners.size(), m_patternType, m_patternSize, m_chessboardSquareWidth, m_corners, m_videoWidth, m_videoHeight, AR_DIST_FUNCTION_VERSION_DEFAULT, param_out, err_min_out, err_avg_out, err_max_out);
282282
}
283283

284284
Calibration::~Calibration()

calc.cpp

Lines changed: 103 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
#include <opencv2/calib3d/calib3d.hpp>
4242
#include <opencv2/core/core_c.h>
4343

44-
static ARdouble getSizeFactor(ARdouble dist_factor[], int xsize, int ysize, int dist_function_version);
45-
static void convParam(float intr[3][4], float dist[4], int xsize, int ysize, ARParam *param);
44+
static void convParam(const float intr[3][4], const float dist[AR_DIST_FACTOR_NUM_MAX], const int xsize, const int ysize, const int dist_function_version, ARParam *param);
45+
static ARdouble getSizeFactor(ARdouble const dist_factor[AR_DIST_FACTOR_NUM_MAX], const int xsize, const int ysize, const int dist_function_version);
4646

4747
static void calcChessboardCorners(const Calibration::CalibrationPatternType patternType, cv::Size patternSize, float patternSpacing, std::vector<cv::Point3f>& corners)
4848
{
@@ -74,20 +74,28 @@ void calc(const int capturedImageNum,
7474
const std::vector<std::vector<cv::Point2f> >& cornerSet,
7575
const int width,
7676
const int height,
77+
const int dist_function_version,
7778
ARParam *param_out,
7879
ARdouble *err_min_out,
7980
ARdouble *err_avg_out,
8081
ARdouble *err_max_out)
8182
{
82-
int i, j, k;
83+
if (dist_function_version != 5 && dist_function_version != 4) {
84+
ARLOGe("Unsupported distortion function version %d.\n", dist_function_version);
85+
return;
86+
}
8387

84-
// Options.
88+
// Set version.
8589
int flags = 0;
90+
cv::Mat distortionCoeff;
91+
if (dist_function_version == 5) {
92+
distortionCoeff = cv::Mat::zeros(12, 1, CV_64F);
93+
flags |= cv::CALIB_RATIONAL_MODEL|cv::CALIB_THIN_PRISM_MODEL;
94+
} else /* dist_function_version == 4 */ {
95+
distortionCoeff = cv::Mat::zeros(5, 1, CV_64F);
96+
flags |= cv::CALIB_FIX_K3;
97+
}
8698
double aspectRatio = 1.0;
87-
//flags |= cv::CALIB_USE_INTRINSIC_GUESS;
88-
//flags |= cv::CALIB_FIX_ASPECT_RATIO;
89-
//flags |= cv::CALIB_FIX_PRINCIPAL_POINT;
90-
//flags |= cv::CALIB_ZERO_TANGENT_DIST;
9199

92100
// Set up object points.
93101
std::vector<std::vector<cv::Point3f> > objectPoints(1);
@@ -98,12 +106,11 @@ void calc(const int capturedImageNum,
98106
if (flags & cv::CALIB_FIX_ASPECT_RATIO)
99107
intrinsics.at<double>(0,0) = aspectRatio;
100108

101-
cv::Mat distortionCoeff = cv::Mat::zeros(4, 1, CV_64F);
102109
std::vector<cv::Mat> rotationVectors;
103110
std::vector<cv::Mat> translationVectors;
104111

105112
double rms = calibrateCamera(objectPoints, cornerSet, cv::Size(width, height), intrinsics,
106-
distortionCoeff, rotationVectors, translationVectors, flags|cv::CALIB_FIX_K3|cv::CALIB_FIX_K4|cv::CALIB_FIX_K5);
113+
distortionCoeff, rotationVectors, translationVectors, flags);
107114

108115
ARLOGi("RMS error reported by calibrateCamera: %g\n", rms);
109116

@@ -112,19 +119,22 @@ void calc(const int capturedImageNum,
112119

113120

114121
float intr[3][4];
115-
float dist[4];
122+
float dist[AR_DIST_FACTOR_NUM_MAX];
116123
ARParam param;
124+
int i, j, k;
117125

118126
for (j = 0; j < 3; j++) {
119127
for (i = 0; i < 3; i++) {
120128
intr[j][i] = (float)intrinsics.at<double>(j, i);
121129
}
122130
intr[j][3] = 0.0f;
123131
}
124-
for (i = 0; i < 4; i++) {
125-
dist[i] = (float)distortionCoeff.at<double>(i);
132+
if (dist_function_version == 5) {
133+
for (i = 0; i < 12; i++) dist[i] = (float)distortionCoeff.at<double>(i);
134+
} else /* dist_function_version == 4 */ {
135+
for (i = 0; i < 4; i++) dist[i] = (float)distortionCoeff.at<double>(i);
126136
}
127-
convParam(intr, dist, width, height, &param);
137+
convParam(intr, dist, width, height, dist_function_version, &param);
128138
arParamDisp(&param);
129139

130140
CvMat *rotationVector;
@@ -187,24 +197,45 @@ void calc(const int capturedImageNum,
187197
cvReleaseMat(&rotationMatrix);
188198
}
189199

190-
void convParam(float intr[3][4], float dist[4], int xsize, int ysize, ARParam *param)
200+
static void convParam(const float intr[3][4], const float dist[AR_DIST_FACTOR_NUM_MAX], const int xsize, const int ysize, const int dist_function_version, ARParam *param)
191201
{
192202
double s;
193203
int i, j;
194-
195-
param->dist_function_version = 4;
204+
205+
if (dist_function_version != 5 && dist_function_version != 4) {
206+
ARLOGe("Unsupported distortion function version %d.\n", dist_function_version);
207+
return;
208+
}
209+
210+
param->dist_function_version = dist_function_version;
196211
param->xsize = xsize;
197212
param->ysize = ysize;
198213

199-
param->dist_factor[0] = (ARdouble)dist[0]; /* k1 */
200-
param->dist_factor[1] = (ARdouble)dist[1]; /* k2 */
201-
param->dist_factor[2] = (ARdouble)dist[2]; /* p1 */
202-
param->dist_factor[3] = (ARdouble)dist[3]; /* p2 */
203-
param->dist_factor[4] = (ARdouble)intr[0][0]; /* fx */
204-
param->dist_factor[5] = (ARdouble)intr[1][1]; /* fy */
205-
param->dist_factor[6] = (ARdouble)intr[0][2]; /* x0 */
206-
param->dist_factor[7] = (ARdouble)intr[1][2]; /* y0 */
207-
param->dist_factor[8] = (ARdouble)1.0; /* s */
214+
param->dist_factor[0] = (ARdouble)dist[0]; /* k1 */
215+
param->dist_factor[1] = (ARdouble)dist[1]; /* k2 */
216+
param->dist_factor[2] = (ARdouble)dist[2]; /* p1 */
217+
param->dist_factor[3] = (ARdouble)dist[3]; /* p2 */
218+
if (dist_function_version == 5) {
219+
param->dist_factor[4] = (ARdouble)dist[4]; /* k3 */
220+
param->dist_factor[5] = (ARdouble)dist[5]; /* k4 */
221+
param->dist_factor[6] = (ARdouble)dist[6]; /* k5 */
222+
param->dist_factor[7] = (ARdouble)dist[7]; /* k6 */
223+
param->dist_factor[8] = (ARdouble)dist[8]; /* s1 */
224+
param->dist_factor[9] = (ARdouble)dist[9]; /* s2 */
225+
param->dist_factor[10] = (ARdouble)dist[10]; /* s3 */
226+
param->dist_factor[11] = (ARdouble)dist[11]; /* s4 */
227+
param->dist_factor[12] = (ARdouble)intr[0][0]; /* fx */
228+
param->dist_factor[13] = (ARdouble)intr[1][1]; /* fy */
229+
param->dist_factor[14] = (ARdouble)intr[0][2]; /* cx */
230+
param->dist_factor[15] = (ARdouble)intr[1][2]; /* cy */
231+
param->dist_factor[16] = (ARdouble)1.0; /* s */
232+
} else /* dist_function_version == 4 */ {
233+
param->dist_factor[4] = (ARdouble)intr[0][0]; /* fx */
234+
param->dist_factor[5] = (ARdouble)intr[1][1]; /* fy */
235+
param->dist_factor[6] = (ARdouble)intr[0][2]; /* cx */
236+
param->dist_factor[7] = (ARdouble)intr[1][2]; /* cy */
237+
param->dist_factor[8] = (ARdouble)1.0; /* s */
238+
}
208239

209240
for (j = 0; j < 3; j++) {
210241
for (i = 0; i < 4; i++) {
@@ -217,55 +248,71 @@ void convParam(float intr[3][4], float dist[4], int xsize, int ysize, ARParam *p
217248
param->mat[0][1] /= s;
218249
param->mat[1][0] /= s;
219250
param->mat[1][1] /= s;
220-
param->dist_factor[8] = s;
251+
if (dist_function_version == 5) {
252+
param->dist_factor[16] = s;
253+
} else /* dist_function_version == 4 */ {
254+
param->dist_factor[8] = s;
255+
}
221256
}
222257

223-
ARdouble getSizeFactor(ARdouble dist_factor[], int xsize, int ysize, int dist_function_version)
258+
static ARdouble getSizeFactor(const ARdouble dist_factor[AR_DIST_FACTOR_NUM_MAX], const int xsize, const int ysize, const int dist_function_version)
224259
{
225260
ARdouble ox, oy, ix, iy;
226261
ARdouble olen, ilen;
227262
ARdouble sf, sf1;
263+
ARdouble cx, cy;
264+
265+
if (dist_function_version == 5) {
266+
cx = dist_factor[14];
267+
cy = dist_factor[15];
268+
} else if (dist_function_version == 4) {
269+
cx = dist_factor[6];
270+
cy = dist_factor[7];
271+
} else {
272+
ARLOGe("Unsupported distortion function version %d.\n", dist_function_version);
273+
return 1.0;
274+
}
228275

229276
sf = 100.0f;
230277

231278
ox = 0.0f;
232-
oy = dist_factor[7];
233-
olen = dist_factor[6];
279+
oy = cy;
280+
olen = cx;
234281
arParamObserv2Ideal(dist_factor, ox, oy, &ix, &iy, dist_function_version);
235-
ilen = dist_factor[6] - ix;
282+
ilen = cx - ix;
236283
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
237284
if (ilen > 0.0f) {
238285
sf1 = ilen / olen;
239286
if (sf1 < sf) sf = sf1;
240287
}
241288

242289
ox = xsize;
243-
oy = dist_factor[7];
244-
olen = xsize - dist_factor[6];
290+
oy = cy;
291+
olen = xsize - cx;
245292
arParamObserv2Ideal(dist_factor, ox, oy, &ix, &iy, dist_function_version);
246-
ilen = ix - dist_factor[6];
293+
ilen = ix - cx;
247294
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
248295
if (ilen > 0.0f) {
249296
sf1 = ilen / olen;
250297
if (sf1 < sf) sf = sf1;
251298
}
252299

253-
ox = dist_factor[6];
300+
ox = cx;
254301
oy = 0.0;
255-
olen = dist_factor[7];
302+
olen = cy;
256303
arParamObserv2Ideal(dist_factor, ox, oy, &ix, &iy, dist_function_version);
257-
ilen = dist_factor[7] - iy;
304+
ilen = cy - iy;
258305
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
259306
if (ilen > 0.0f) {
260307
sf1 = ilen / olen;
261308
if (sf1 < sf) sf = sf1;
262309
}
263310

264-
ox = dist_factor[6];
311+
ox = cx;
265312
oy = ysize;
266-
olen = ysize - dist_factor[7];
313+
olen = ysize - cy;
267314
arParamObserv2Ideal(dist_factor, ox, oy, &ix, &iy, dist_function_version);
268-
ilen = iy - dist_factor[7];
315+
ilen = iy - cy;
269316
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
270317
if (ilen > 0.0f) {
271318
sf1 = ilen / olen;
@@ -276,15 +323,15 @@ ARdouble getSizeFactor(ARdouble dist_factor[], int xsize, int ysize, int dist_fu
276323
ox = 0.0f;
277324
oy = 0.0f;
278325
arParamObserv2Ideal(dist_factor, ox, oy, &ix, &iy, dist_function_version);
279-
ilen = dist_factor[6] - ix;
280-
olen = dist_factor[6];
326+
ilen = cx - ix;
327+
olen = cx;
281328
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
282329
if (ilen > 0.0f) {
283330
sf1 = ilen / olen;
284331
if (sf1 < sf) sf = sf1;
285332
}
286-
ilen = dist_factor[7] - iy;
287-
olen = dist_factor[7];
333+
ilen = cy - iy;
334+
olen = cy;
288335
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
289336
if (ilen > 0.0f) {
290337
sf1 = ilen / olen;
@@ -294,15 +341,15 @@ ARdouble getSizeFactor(ARdouble dist_factor[], int xsize, int ysize, int dist_fu
294341
ox = xsize;
295342
oy = 0.0f;
296343
arParamObserv2Ideal(dist_factor, ox, oy, &ix, &iy, dist_function_version);
297-
ilen = ix - dist_factor[6];
298-
olen = xsize - dist_factor[6];
344+
ilen = ix - cx;
345+
olen = xsize - cx;
299346
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
300347
if (ilen > 0.0f) {
301348
sf1 = ilen / olen;
302349
if (sf1 < sf) sf = sf1;
303350
}
304-
ilen = dist_factor[7] - iy;
305-
olen = dist_factor[7];
351+
ilen = cy - iy;
352+
olen = cy;
306353
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
307354
if (ilen > 0.0f) {
308355
sf1 = ilen / olen;
@@ -312,15 +359,15 @@ ARdouble getSizeFactor(ARdouble dist_factor[], int xsize, int ysize, int dist_fu
312359
ox = 0.0f;
313360
oy = ysize;
314361
arParamObserv2Ideal(dist_factor, ox, oy, &ix, &iy, dist_function_version);
315-
ilen = dist_factor[6] - ix;
316-
olen = dist_factor[6];
362+
ilen = cx - ix;
363+
olen = cx;
317364
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
318365
if (ilen > 0.0f) {
319366
sf1 = ilen / olen;
320367
if (sf1 < sf) sf = sf1;
321368
}
322-
ilen = iy - dist_factor[7];
323-
olen = ysize - dist_factor[7];
369+
ilen = iy - cy;
370+
olen = ysize - cy;
324371
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
325372
if (ilen > 0.0f) {
326373
sf1 = ilen / olen;
@@ -330,15 +377,15 @@ ARdouble getSizeFactor(ARdouble dist_factor[], int xsize, int ysize, int dist_fu
330377
ox = xsize;
331378
oy = ysize;
332379
arParamObserv2Ideal(dist_factor, ox, oy, &ix, &iy, dist_function_version);
333-
ilen = ix - dist_factor[6];
334-
olen = xsize - dist_factor[6];
380+
ilen = ix - cx;
381+
olen = xsize - cx;
335382
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
336383
if (ilen > 0.0f) {
337384
sf1 = ilen / olen;
338385
if (sf1 < sf) sf = sf1;
339386
}
340-
ilen = iy - dist_factor[7];
341-
olen = ysize - dist_factor[7];
387+
ilen = iy - cy;
388+
olen = ysize - cy;
342389
//ARPRINT("Olen = %f, Ilen = %f, s = %f\n", olen, ilen, ilen / olen);
343390
if (ilen > 0.0f) {
344391
sf1 = ilen / olen;

calc.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ void calc(const int capturedImageNum,
4949
const std::vector<std::vector<cv::Point2f> >& cornerSet,
5050
const int width,
5151
const int height,
52+
const int dist_function_version,
5253
ARParam *param_out,
5354
ARdouble *err_min_out,
5455
ARdouble *err_avg_out,

iOS/artoolkitX Camera Calibration Utility.xcodeproj/project.pbxproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@
387387
KnownAssetTags = (
388388
New,
389389
);
390-
LastUpgradeCheck = 0920;
390+
LastUpgradeCheck = 0930;
391391
ORGANIZATIONNAME = artoolkitx.org;
392392
TargetAttributes = {
393393
4A4793461E80CDBE002C3631 = {
@@ -507,12 +507,14 @@
507507
CLANG_WARN_BOOL_CONVERSION = YES;
508508
CLANG_WARN_COMMA = YES;
509509
CLANG_WARN_CONSTANT_CONVERSION = YES;
510+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
510511
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
511512
CLANG_WARN_EMPTY_BODY = YES;
512513
CLANG_WARN_ENUM_CONVERSION = YES;
513514
CLANG_WARN_INFINITE_RECURSION = YES;
514515
CLANG_WARN_INT_CONVERSION = YES;
515516
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
517+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
516518
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
517519
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
518520
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -569,12 +571,14 @@
569571
CLANG_WARN_BOOL_CONVERSION = YES;
570572
CLANG_WARN_COMMA = YES;
571573
CLANG_WARN_CONSTANT_CONVERSION = YES;
574+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
572575
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
573576
CLANG_WARN_EMPTY_BODY = YES;
574577
CLANG_WARN_ENUM_CONVERSION = YES;
575578
CLANG_WARN_INFINITE_RECURSION = YES;
576579
CLANG_WARN_INT_CONVERSION = YES;
577580
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
581+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
578582
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
579583
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
580584
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;

0 commit comments

Comments
 (0)