⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecalmain.c

📁 标准tsai摄像机标定源代码。(两步标定)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************\*                                                                               ** This file contains routines for calibrating the extrinsic parameters of       ** Tsai's 11 parameter camera model.  The inputs to the routines are a set of    ** precalibrated intrinsic camera parameters:                                    **                                                                               **       f       - effective focal length of the pin hole camera                 **       kappa1  - 1st order radial lens distortion coefficient                  **       Cx, Cy  - coordinates of center of radial lens distortion               **                 (also used as the piercing point of the camera coordinate     **                  frame's Z axis with the camera's sensor plane)               **       sx      - uncertainty factor for scale of horizontal scanline           **                                                                               ** and a set of calibration data consisting of the (x,y,z) world coordinates of  ** a feature point (in mm) and the corresponding coordinates (Xf,Yf) (in pixels) ** of the feature point in the image.  The outputs of the routines are the 6     ** external (also called extrinsic or exterior) camera parameters:               **                                                                               **       Rx, Ry, Rz, Tx, Ty, Tz  - rotational and translational components of    **                                 the transform between the world's coordinate  **                                 frame and the camera's coordinate frame.      **                                                                               ** describing the camera's pose.                                                 **                                                                               ** This file provides two routines:                                              **                                                                               **       coplanar_extrinsic_parameter_estimation ()                              ** and                                                                           **       noncoplanar_extrinsic_parameter_estimation ()                           **                                                                               ** which are used respectively for coplanar and non-coplanar calibration data.   **                                                                               ** Initial estimates for the extrinsic camera parameters are determined using a  ** modification of the first stage of Tsai's algorithm.  These estimates are     ** then refined using iterative non-linear optimization.                         **                                                                               **                                                                               ** History                                                                       ** -------                                                                       **                                                                               ** 15-Oct-95  Reg Willson (rgwillson@mmm.com) at 3M St. Paul, MN                 **       Added routines to coplanar_extrinsic_parameter_estimation to pick       **       the correct rotation matrix solution from the two possible solutions.   **       Bug tracked down by Pete Rander <Peter.Rander@IUS4.IUS.CS.CMU.EDU>.     **                                                                               ** 20-May-95  Reg Willson (rgwillson@mmm.com) at 3M St. Paul, MN                 **       Return the error to lmdif rather than the squared error.                **         lmdif calculates the squared error internally during optimization.    **         Before this change calibration was essentially optimizing error^4.    **                                                                               ** 02-Apr-95  Reg Willson (rgwillson@mmm.com) at 3M St. Paul, MN                 **       Rewrite memory allocation to avoid memory alignment problems            **       on some machines.                                                       **       Strip out IMSL code.  MINPACK seems to work fine.                       **       Filename changes for DOS port.                                          **                                                                               ** 04-Jun-94  Reg Willson (rgwillson@mmm.com) at 3M St. Paul, MN                 **       Added alternate macro definitions for less common math functions.       **                                                                               ** 25-Mar-94  Torfi Thorhallsson (torfit@verk.hi.is) at the University of Iceland* *       Added a new version of the routine epe_optimize() which uses the        **       *public domain* MINPACK optimization library instead of IMSL.           **       To select the new routine, compile this file with the flag -DMINPACK    **                                                                               ** 11-Nov-93  Reg Willson (rgw@cs.cmu.edu) at Carnegie-Mellon University         **       Original implementation.                                                **                                                                               *\*******************************************************************************/#include <stdlib.h>#include <stdio.h>#include <math.h>#include <errno.h>#include "matrix/matrix.h"#include "cal_main.h"#include "minpack/f2c.h"/***********************************************************************\* Routines for coplanar extrinsic parameter estimation			*\***********************************************************************/void      cepe_compute_U (U)    double    U[];{    dmat      M,              a,              b;    double    Xd,              Yd,              Xu,              Yu,              distortion_factor;    int       i;    M = newdmat (0, (cd.point_count - 1), 0, 4, &errno);    if (errno) {	fprintf (stderr, "cepe compute U: unable to allocate matrix M\n");	exit (-1);    }    a = newdmat (0, 4, 0, 0, &errno);    if (errno) {	fprintf (stderr, "cepe compute U: unable to allocate vector a\n");	exit (-1);    }    b = newdmat (0, (cd.point_count - 1), 0, 0, &errno);    if (errno) {	fprintf (stderr, "cepe compute U: unable to allocate vector b\n");	exit (-1);    }    for (i = 0; i < cd.point_count; i++) {	/* convert from image coordinates to distorted sensor coordinates */	Xd = cp.dpx * (cd.Xf[i] - cp.Cx) / cp.sx;	Yd = cp.dpy * (cd.Yf[i] - cp.Cy);	/* convert from distorted sensor coordinates to undistorted sensor coordinates */	distortion_factor = 1 + cc.kappa1 * (SQR (Xd) + SQR (Yd));	Xu = Xd * distortion_factor;	Yu = Yd * distortion_factor;	M.el[i][0] = Yu * cd.xw[i];	M.el[i][1] = Yu * cd.yw[i];	M.el[i][2] = Yu;	M.el[i][3] = -Xu * cd.xw[i];	M.el[i][4] = -Xu * cd.yw[i];	b.el[i][0] = Xu;    }    if (solve_system (M, a, b)) {	fprintf (stderr, "cepe compute U: unable to solve system  Ma=b\n");	exit (-1);    }    U[0] = a.el[0][0];    U[1] = a.el[1][0];    U[2] = a.el[2][0];    U[3] = a.el[3][0];    U[4] = a.el[4][0];    freemat (M);    freemat (a);    freemat (b);}void      cepe_compute_Tx_and_Ty (U)    double    U[];{    double    Tx,              Ty,              Ty_squared,              x,              y,              Sr,              r1p,              r2p,              r4p,              r5p,              r1,              r2,              r4,              r5,              distance,              far_distance;    int       i,              far_point;    r1p = U[0];    r2p = U[1];    r4p = U[3];    r5p = U[4];    /* first find the square of the magnitude of Ty */    if ((fabs (r1p) < EPSILON) && (fabs (r2p) < EPSILON))	Ty_squared = 1 / (SQR (r4p) + SQR (r5p));    else if ((fabs (r4p) < EPSILON) && (fabs (r5p) < EPSILON))	Ty_squared = 1 / (SQR (r1p) + SQR (r2p));    else if ((fabs (r1p) < EPSILON) && (fabs (r4p) < EPSILON))	Ty_squared = 1 / (SQR (r2p) + SQR (r5p));    else if ((fabs (r2p) < EPSILON) && (fabs (r5p) < EPSILON))	Ty_squared = 1 / (SQR (r1p) + SQR (r4p));    else {	Sr = SQR (r1p) + SQR (r2p) + SQR (r4p) + SQR (r5p);	Ty_squared = (Sr - sqrt (SQR (Sr) - 4 * SQR (r1p * r5p - r4p * r2p))) /	 (2 * SQR (r1p * r5p - r4p * r2p));    }    /* find a point that is far from the image center */    far_distance = 0;    far_point = 0;    for (i = 0; i < cd.point_count; i++)	if ((distance = SQR (cd.Xf[i] - cp.Cx) + SQR (cd.Yf[i] - cp.Cy)) > far_distance) {	    far_point = i;	    far_distance = distance;	}    /* now find the sign for Ty */    /* start by assuming Ty > 0 */    Ty = sqrt (Ty_squared);    r1 = U[0] * Ty;    r2 = U[1] * Ty;    Tx = U[2] * Ty;    r4 = U[3] * Ty;    r5 = U[4] * Ty;    x = r1 * cd.xw[far_point] + r2 * cd.yw[far_point] + Tx;    y = r4 * cd.xw[far_point] + r5 * cd.yw[far_point] + Ty;    /* flip Ty if we guessed wrong */    if ((SIGNBIT (x) != SIGNBIT (cd.Xf[far_point] - cp.Cx)) ||	(SIGNBIT (y) != SIGNBIT (cd.Yf[far_point] - cp.Cy)))	Ty = -Ty;    /* update the calibration constants */    cc.Tx = U[2] * Ty;    cc.Ty = Ty;}void      cepe_compute_R (U)    double    U[];{    double    r1,              r2,              r3,              r4,              r5,              r6,              r7,              r8,              r9;    r1 = U[0] * cc.Ty;    r2 = U[1] * cc.Ty;    r3 = sqrt (1 - SQR (r1) - SQR (r2));    r4 = U[3] * cc.Ty;    r5 = U[4] * cc.Ty;    r6 = sqrt (1 - SQR (r4) - SQR (r5));    if (!SIGNBIT (r1 * r4 + r2 * r5))	r6 = -r6;    /* use the outer product of the first two rows to get the last row */    r7 = r2 * r6 - r3 * r5;    r8 = r3 * r4 - r1 * r6;    r9 = r1 * r5 - r2 * r4;    /* update the calibration constants */    cc.r1 = r1;    cc.r2 = r2;    cc.r3 = r3;    cc.r4 = r4;    cc.r5 = r5;    cc.r6 = r6;    cc.r7 = r7;    cc.r8 = r8;    cc.r9 = r9;    /* fill in cc.Rx, cc.Ry and cc.Rz */    solve_RPY_transform ();}void      cepe_compute_approximate_f (f)    double   *f;{    dmat      M,              a,              b;    double    Yd;    int       i;    M = newdmat (0, (cd.point_count - 1), 0, 1, &errno);    if (errno) {	fprintf (stderr, "cepe compute apx: unable to allocate matrix M\n");	exit (-1);    }    a = newdmat (0, 1, 0, 0, &errno);    if (errno) {	fprintf (stderr, "cepe compute apx: unable to allocate vector a\n");	exit (-1);    }    b = newdmat (0, (cd.point_count - 1), 0, 0, &errno);    if (errno) {	fprintf (stderr, "cepe compute apx: unable to allocate vector b\n");	exit (-1);    }    for (i = 0; i < cd.point_count; i++) {	Yd = cp.dpy * (cd.Yf[i] - cp.Cy);	M.el[i][0] = cc.r4 * cd.xw[i] + cc.r5 * cd.yw[i] + cc.Ty;	M.el[i][1] = -Yd;	b.el[i][0] = (cc.r7 * cd.xw[i] + cc.r8 * cd.yw[i]) * Yd;    }    if (solve_system (M, a, b)) {	fprintf (stderr, "cepe compute apx: unable to solve system  Ma=b\n");	exit (-1);    }    /* return the approximate effective focal length */    *f = a.el[0][0];    freemat (M);    freemat (a);    freemat (b);}/***********************************************************************\* Routines for noncoplanar extrinsic parameter estimation		*\***********************************************************************/void      ncepe_compute_U (U)    double    U[];{    dmat      M,              a,              b;    double    Xu,              Yu,              Xd,              Yd,              distortion_factor;    int       i;    M = newdmat (0, (cd.point_count - 1), 0, 6, &errno);    if (errno) {	fprintf (stderr, "ncepe compute U: unable to allocate matrix M\n");	exit (-1);    }    a = newdmat (0, 6, 0, 0, &errno);    if (errno) {	fprintf (stderr, "ncepe compute U: unable to allocate vector a\n");	exit (-1);    }    b = newdmat (0, (cd.point_count - 1), 0, 0, &errno);    if (errno) {	fprintf (stderr, "ncepe compute U: unable to allocate vector b\n");	exit (-1);    }    for (i = 0; i < cd.point_count; i++) {	/* convert from image coordinates to distorted sensor coordinates */	Xd = cp.dpx * (cd.Xf[i] - cp.Cx) / cp.sx;	Yd = cp.dpy * (cd.Yf[i] - cp.Cy);	/* convert from distorted sensor coordinates to undistorted sensor coordinates */	distortion_factor = 1 + cc.kappa1 * (SQR (Xd) + SQR (Yd));	Xu = Xd * distortion_factor;	Yu = Yd * distortion_factor;	M.el[i][0] = Yu * cd.xw[i];	M.el[i][1] = Yu * cd.yw[i];	M.el[i][2] = Yu * cd.zw[i];	M.el[i][3] = Yu;	M.el[i][4] = -Xu * cd.xw[i];	M.el[i][5] = -Xu * cd.yw[i];	M.el[i][6] = -Xu * cd.zw[i];	b.el[i][0] = Xu;    }    if (solve_system (M, a, b)) {	fprintf (stderr, "ncepe compute U: unable to solve system  Ma=b\n");	exit (-1);    }    U[0] = a.el[0][0];    U[1] = a.el[1][0];    U[2] = a.el[2][0];    U[3] = a.el[3][0];    U[4] = a.el[4][0];    U[5] = a.el[5][0];    U[6] = a.el[6][0];    freemat (M);    freemat (a);    freemat (b);}void      ncepe_compute_Tx_and_Ty (U)    double    U[];{    double    Tx,              Ty,              Ty_squared,              x,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -