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

📄 cal_main.c

📁 tsai经典标定程序 MATLAB语言
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************\*                                                                               ** This file contains routines for calibrating Tsai's 11 parameter camera model. ** The camera model is based on the pin hole model of 3D-2D perspective          ** projection with 1st order radial lens distortion.  The model consists of      ** 5 internal (also called intrinsic or interior) 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 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.      **                                                                               ** Data for model calibration consists 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.  Two types of calibration are available:   **                                                                               **       coplanar     - all of the calibration points lie in a single plane      **       non-coplanar - the calibration points do not lie in a single plane      **                                                                               ** This file contains routines for two levels of calibration.  The first level   ** of calibration is a direct implementation of Tsai's algorithm in which only   ** the f, Tz and kappa1 parameters are optimized for.  The routines are:         **                                                                               **       coplanar_calibration ()                                                 **       noncoplanar_calibration ()                                              **                                                                               ** The second level of calibration optimizes for everything.  This level is      ** very slow but provides the most accurate calibration.  The routines are:      **                                                                               **       coplanar_calibration_with_full_optimization ()                          **       noncoplanar_calibration_with_full_optimization ()                       **                                                                               ** Routines are also provided for initializing camera parameter variables        ** for five of our camera/frame grabber systems.  These routines are:            **                                                                               **       initialize_photometrics_parms ()                                        **       initialize_general_imaging_mos5300_matrox_parms ()                      **       initialize_panasonic_gp_mf702_matrox_parms ()                           **       initialize_sony_xc75_matrox_parms ()                                    **       initialize_sony_xc77_matrox_parms ()                                    **       initialize_sony_xc57_androx_parms ()                                    **                                                                               **                                                                               ** External routines                                                             ** -----------------                                                             **                                                                               ** Nonlinear optimization for these camera calibration routines is performed     ** by the MINPACK lmdif subroutine.  lmdif uses a modified Levenberg-Marquardt   ** with a jacobian calculated by a forward-difference approximation.             ** The MINPACK FORTRAN routines were translated into C generated using f2c.      **                                                                               ** Matrix operations (inversions, multiplications, etc.) are also provided by    ** external routines.                                                            **                                                                               **                                                                               ** Extra notes                                                                   ** -----------                                                                   **                                                                               ** An explanation of the basic algorithms and description of the variables       ** can be found in several publications, including:                              **                                                                               ** "An Efficient and Accurate Camera Calibration Technique for 3D Machine        **  Vision", Roger Y. Tsai, Proceedings of IEEE Conference on Computer Vision    **  and Pattern Recognition, Miami Beach, FL, 1986, pages 364-374.               **                                                                               **  and                                                                          **                                                                               ** "A versatile Camera Calibration Technique for High-Accuracy 3D Machine        **  Vision Metrology Using Off-the-Shelf TV Cameras and Lenses", Roger Y. Tsai,  **  IEEE Journal of Robotics and Automation, Vol. RA-3, No. 4, August 1987,      **  pages 323-344.                                                               **                                                                               **                                                                               ** Notation                                                                      ** --------                                                                      **                                                                               ** The camera's X axis runs along increasing column coordinates in the           ** image/frame.  The Y axis runs along increasing row coordinates.               **                                                                               ** pix == image/frame grabber picture element                                    ** sel == camera sensor element                                                  **                                                                               ** Internal routines starting with "cc_" are for coplanar calibration.           ** Internal routines starting with "ncc_" are for noncoplanar calibration.       **                                                                               **                                                                               ** History                                                                       ** -------                                                                       **                                                                               ** 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.    **       Put transform and evaluation routines into separate files.              **                                                                               ** 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                 **       Replaced ncc_compute_Xdp_and_Ydp with ncc_compute_Xd_Yd_and_r_squared.  **         (effectively propagates the 22-Mar-94 to the non-coplanar routines)   **       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 routines:                                    **            cc_compute_exact_f_and_Tz ()                                       **            cc_five_parm_optimization_with_late_distortion_removal ()          **            cc_five_parm_optimization_with_early_distortion_removal ()         **            cc_nic_optimization ()                                             **            cc_full_optimization ()                                            **            ncc_compute_exact_f_and_Tz ()                                      **            ncc_nic_optimization ()                                            **            ncc_full_optimization ()                                           **                                                                               **       The new routines use the *public domain* MINPACK library for            **       optimization instead of the commercial IMSL library.                    **       To select the new routines, compile this file with the flag -DMINPACK   **                                                                               ** 22-Mar-94  Torfi Thorhallsson (torfit@verk.hi.is) at the University of Iceland**       Fixed a bug in cc_nic_optimization_error and cc_full_optimization_error.**       A division by cp.sx was missing.                                        **                                                                               ** 15-Feb-94  Reg Willson (rgw@cs.cmu.edu) at Carnegie-Mellon University         **       Included Frederic Devernay's (<Frederic.Devernay@sophia.inria.fr>)	**	significantly improved routine for converting from undistorted to	**	distorted sensor coordinates.  Rather than iteratively solving a	**	system of two non-linear equations to perform the conversion, the 	**	new routine algebraically solves a cubic polynomial in Rd (using	**	the Cardan method).							**                                                                               ** 14-Feb-94  Reg Willson (rgw@cs.cmu.edu) at Carnegie-Mellon University         **	Fixed a coding bug in ncc_compute_R and ncc_compute_better_R.           **       The r4, r5, and r6 terms should not be divided by cp.sx.                **       Bug reported by: Volker Rodehorst <vr@cs.tu-berlin.de>                  **                                                                               ** 04-Jul-93  Reg Willson (rgw@cs.cmu.edu) at Carnegie-Mellon University         **	Added new routines to evaluate the accuracy of camera calibration.      **                                                                               **       Added check for coordinate handedness problem in calibration data.      **                                                                               ** 01-May-93  Reg Willson (rgw@cs.cmu.edu) at Carnegie-Mellon University         **	For efficiency the non-linear optimizations are now all based on	**	the minimization of squared error in undistorted image coordinates      **	instead of the squared error in distorted image coordinates.		**										**	New routine for inverse perspective projection.				**										** 14-Feb-93  Reg Willson (rgw@cs.cmu.edu) at Carnegie-Mellon University         **       Bug fixes and speed ups.                                                **                                                                               ** 07-Feb-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"/* Variables used by the subroutines for I/O (perhaps not the best way of doing this) */struct camera_parameters cp;struct calibration_data cd;struct calibration_constants cc;/* Local working storage */double    Xd[MAX_POINTS],          Yd[MAX_POINTS],          r_squared[MAX_POINTS],          U[7];char   camera_type[256] = "unknown";/************************************************************************/.
void      initialize_photometrics_parms (){    strcpy (camera_type, "Photometrics Star I");    cp.Ncx = 576;		/* [sel]        */    cp.Nfx = 576;		/* [pix]        */    cp.dx = 0.023;		/* [mm/sel]     */    cp.dy = 0.023;		/* [mm/sel]     */    cp.dpx = cp.dx * cp.Ncx / cp.Nfx;	/* [mm/pix]     */    cp.dpy = cp.dy;		/* [mm/pix]     */    cp.Cx = 576 / 2;		/* [pix]        */    cp.Cy = 384 / 2;		/* [pix]        */    cp.sx = 1.0;		/* []		 */    /* something a bit more realistic */    cp.Cx = 258.0;    cp.Cy = 204.0;}/************************************************************************/void      initialize_general_imaging_mos5300_matrox_parms (){    strcpy (camera_type, "General Imaging MOS5300 + Matrox");    cp.Ncx = 649;		/* [sel]        */    cp.Nfx = 512;		/* [pix]        */    cp.dx = 0.015;		/* [mm/sel]     */    cp.dy = 0.015;		/* [mm/sel]     */    cp.dpx = cp.dx * cp.Ncx / cp.Nfx;	/* [mm/pix]     */    cp.dpy = cp.dy;		/* [mm/pix]     */    cp.Cx = 512 / 2;		/* [pix]        */    cp.Cy = 480 / 2;		/* [pix]        */    cp.sx = 1.0;		/* []		 */}/************************************************************************/void      initialize_panasonic_gp_mf702_matrox_parms (){    strcpy (camera_type, "Panasonic GP-MF702 + Matrox");    cp.Ncx = 649;		/* [sel]        */    cp.Nfx = 512;		/* [pix]        */    cp.dx = 0.015;		/* [mm/sel]     */    cp.dy = 0.015;		/* [mm/sel]     */    cp.dpx = cp.dx * cp.Ncx / cp.Nfx;	/* [mm/pix]     */    cp.dpy = cp.dy;		/* [mm/pix]     */    cp.Cx = 268;		/* [pix]        */    cp.Cy = 248;		/* [pix]        */    cp.sx = 1.078647;		/* []           */}/************************************************************************/void      initialize_sony_xc75_matrox_parms (){    strcpy (camera_type, "Sony XC75 + Matrox");    cp.Ncx = 768;		/* [sel]        */    cp.Nfx = 512;		/* [pix]        */    cp.dx = 0.0084;		/* [mm/sel]     */    cp.dy = 0.0098;		/* [mm/sel]     */    cp.dpx = cp.dx * cp.Ncx / cp.Nfx;	/* [mm/pix]     */    cp.dpy = cp.dy;		/* [mm/pix]     */    cp.Cx = 512 / 2;		/* [pix]        */    cp.Cy = 480 / 2;		/* [pix]        */    cp.sx = 1.0;		/* []           */}/************************************************************************/void      initialize_sony_xc77_matrox_parms (){    strcpy (camera_type, "Sony XC77 + Matrox");    cp.Ncx = 768;		/* [sel]        */    cp.Nfx = 512;		/* [pix]        */    cp.dx = 0.011;		/* [mm/sel]     */    cp.dy = 0.013;		/* [mm/sel]     */    cp.dpx = cp.dx * cp.Ncx / cp.Nfx;	/* [mm/pix]     */    cp.dpy = cp.dy;		/* [mm/pix]     */    cp.Cx = 512 / 2;		/* [pix]        */    cp.Cy = 480 / 2;		/* [pix]        */    cp.sx = 1.0;		/* []           */}/************************************************************************/void      initialize_sony_xc57_androx_parms (){    strcpy (camera_type, "Sony XC57 + Androx");    cp.Ncx = 510;               /* [sel]        */    cp.Nfx = 512;               /* [pix]        */    cp.dx = 0.017;              /* [mm/sel]     */    cp.dy = 0.013;              /* [mm/sel]     */    cp.dpx = cp.dx * cp.Ncx / cp.Nfx;   /* [mm/pix]     */    cp.dpy = cp.dy;             /* [mm/pix]     */    cp.Cx = 512 / 2;            /* [pix]        */    cp.Cy = 480 / 2;            /* [pix]        */    cp.sx = 1.107914;           /* []           */}/************************************************************************//* John Krumm, 9 November 1993                                          *//* This assumes that every other row, starting with the second row from *//* the top, has been removed.  The Xap Shot CCD only has 250 lines, and *//* it inserts new rows in between the real rows to make a full size     *//* picture.  Its algorithm for making these new rows isn't very good,   *//* so it's best just to throw them away.                                *//* The camera's specs give the CCD size as 6.4(V)x4.8(H) mm.            *//* A call to the manufacturer found that the CCD has 250 rows           *//* and 782 columns.  It is underscanned to 242 rows and 739 columns.    *//************************************************************************/void      initialize_xapshot_matrox_parms (){    strcpy (camera_type, "Canon Xap Shot");    cp.Ncx = 739;			/* [sel]        */    cp.Nfx = 512;			/* [pix]        */    cp.dx = 6.4 / 782.0;		/* [mm/sel]     */    cp.dy = 4.8 / 250.0;		/* [mm/sel]     */    cp.dpx = cp.dx * cp.Ncx / cp.Nfx;	/* [mm/pix]     */    cp.dpy = cp.dy;			/* [mm/pix]     */    cp.Cx = 512 / 2;			/* [pix]        */    cp.Cy = 240 / 2;			/* [pix]        */    cp.sx = 1.027753;	/* from noncoplanar calibration *//* []           */}/***********************************************************************\* This routine solves for the roll, pitch and yaw angles (in radians)	** for a given orthonormal rotation matrix (from Richard P. Paul,        ** Robot Manipulators: Mathematics, Programming and Control, p70).       ** Note 1, should the rotation matrix not be orthonormal these will not  ** be the "best fit" roll, pitch and yaw angles.                         ** Note 2, there are actually two possible solutions for the matrix.     ** The second solution can be found by adding 180 degrees to Rz before   ** Ry and Rx are calculated.                                             *\***********************************************************************/void      solve_RPY_transform (){    double    sg,              cg;    cc.Rz = atan2 (cc.r4, cc.r1);    SINCOS (cc.Rz, sg, cg);    cc.Ry = atan2 (-cc.r7, cc.r1 * cg + cc.r4 * sg);    cc.Rx = atan2 (cc.r3 * sg - cc.r6 * cg, cc.r5 * cg - cc.r2 * sg);}/***********************************************************************\* This routine simply takes the roll, pitch and yaw angles and fills in	** the rotation matrix elements r1-r9.					*\***********************************************************************/void      apply_RPY_transform (){    double    sa,              ca,              sb,              cb,              sg,              cg;    SINCOS (cc.Rx, sa, ca);    SINCOS (cc.Ry, sb, cb);    SINCOS (cc.Rz, sg, cg);    cc.r1 = cb * cg;    cc.r2 = cg * sa * sb - ca * sg;    cc.r3 = sa * sg + ca * cg * sb;    cc.r4 = cb * sg;    cc.r5 = sa * sb * sg + ca * cg;    cc.r6 = ca * sb * sg - cg * sa;    cc.r7 = -sb;    cc.r8 = cb * sa;    cc.r9 = ca * cb;}/***********************************************************************\* Routines for coplanar camera calibration	 			*\***********************************************************************/void      cc_compute_Xd_Yd_and_r_squared (){    int       i;    double    Xd_,              Yd_;    for (i = 0; i < cd.point_count; i++) {	Xd[i] = Xd_ = cp.dpx * (cd.Xf[i] - cp.Cx) / cp.sx;	/* [mm] */	Yd[i] = Yd_ = cp.dpy * (cd.Yf[i] - cp.Cy);	        /* [mm] */	r_squared[i] = SQR (Xd_) + SQR (Yd_);                   /* [mm^2] */    }}void      cc_compute_U (){    int       i;    dmat      M,              a,              b;    M = newdmat (0, (cd.point_count - 1), 0, 4, &errno);    if (errno) {	fprintf (stderr, "cc compute U: unable to allocate matrix M\n");        exit (-1);    }    a = newdmat (0, 4, 0, 0, &errno);    if (errno) {	fprintf (stderr, "cc compute U: unable to allocate vector a\n");	exit (-1);    }    b = newdmat (0, (cd.point_count - 1), 0, 0, &errno);    if (errno) {	fprintf (stderr, "cc compute U: unable to allocate vector b\n");

⌨️ 快捷键说明

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