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

📄 cal_main.cpp

📁 有关摄像头定标的C++代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include "stdafx.h"#include <stdlib.h>#include <stdio.h>#include <iostream>#include <math.h>#include <errno.h>#include "matrix/matrix.h"#include "MINPACK/minpack.h"#include "cal_tran.h"#include "cal_main.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");	exit (-1);    }    for (i = 0; i < cd.point_count; i++) {	M.el[i][0] = Yd[i] * cd.xw[i];	M.el[i][1] = Yd[i] * cd.yw[i];	M.el[i][2] = Yd[i];	M.el[i][3] = -Xd[i] * cd.xw[i];	M.el[i][4] = -Xd[i] * cd.yw[i];	b.el[i][0] = Xd[i];    }    if (solve_system (M, a, b)) {	fprintf (stderr, "cc 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      cc_compute_Tx_and_Ty (){    int       i,              far_point;    double    Tx,              Ty,              Ty_squared,              x,              y,              Sr,              r1p,              r2p,              r4p,              r5p,              r1,              r2,              r4,              r5,              distance,              far_distance;    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 = r_squared[i]) > 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 (Xd[far_point])) ||	(SIGNBIT (y) != SIGNBIT (Yd[far_point])))	Ty = -Ty;    /* update the calibration constants */    cc.Tx = U[2] * Ty;    cc.Ty = Ty;}void      cc_compute_R (){    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      cc_compute_approximate_f_and_Tz (){    int       i;    dmat      M,              a,              b;    M = newdmat (0, (cd.point_count - 1), 0, 1, &errno);    if (errno) {	fprintf (stderr, "cc compute apx: unable to allocate matrix M\n");	exit (-1);    }    a = newdmat (0, 1, 0, 0, &errno);    if (errno) {	fprintf (stderr, "cc compute apx: unable to allocate vector a\n");	exit (-1);    }    b = newdmat (0, (cd.point_count - 1), 0, 0, &errno);    if (errno) {	fprintf (stderr, "cc compute apx: unable to allocate vector b\n");	exit (-1);    }    for (i = 0; i < cd.point_count; i++) {	M.el[i][0] = cc.r4 * cd.xw[i] + cc.r5 * cd.yw[i] + cc.Ty;	M.el[i][1] = -Yd[i];	b.el[i][0] = (cc.r7 * cd.xw[i] + cc.r8 * cd.yw[i]) * Yd[i];    }    if (solve_system (M, a, b)) {	fprintf (stderr, "cc compute apx: unable to solve system  Ma=b\n");	exit (-1);    }    /* update the calibration constants */    cc.f = a.el[0][0];//求f和tz;    cc.Tz = a.el[1][0];    cc.kappa1 = 0.0;		/* this is the assumption that our calculation was made under */    freemat (M);    freemat (a);    freemat (b);}/************************************************************************/
//计算精确的F和TZ误差;void      cc_compute_exact_f_and_Tz_error (long *m_ptr, long *n_ptr, double *params, double *err){    int       i;    double    f,              Tz,              kappa1,              xc,              yc,              zc,              Xu_1,              Yu_1,              Xu_2,              Yu_2,              distortion_factor;    f = params[0];    Tz = params[1];    kappa1 = params[2];    for (i = 0; i < cd.point_count; i++) {	/* convert from world coordinates to camera coordinates */
		//世界坐标系和图像坐标系的转化;zw被假设为0;	/* Note: zw is implicitly assumed to be zero for these (coplanar) calculations */	xc = cc.r1 * cd.xw[i] + cc.r2 * cd.yw[i] + cc.Tx;	yc = cc.r4 * cd.xw[i] + cc.r5 * cd.yw[i] + cc.Ty;	zc = cc.r7 * cd.xw[i] + cc.r8 * cd.yw[i] + Tz;	/* convert from camera coordinates to undistorted sensor coordinates */	Xu_1 = f * xc / zc;	Yu_1 = f * yc / zc;	/* convert from distorted sensor coordinates to undistorted sensor coordinates */	distortion_factor = 1 + kappa1 * (SQR (Xd[i]) + SQR (Yd[i]));	Xu_2 = Xd[i] * distortion_factor;	Yu_2 = Yd[i] * distortion_factor;        /* record the error in the undistorted sensor coordinates */        err[i] = hypot (Xu_1 - Xu_2, Yu_1 - Yu_2);    }}void      cc_compute_exact_f_and_Tz (){#define NPARAMS 3    int       i;    /* Parameters needed by MINPACK's lmdif() */    long     m = cd.point_count;    long     n = NPARAMS;    double  x[NPARAMS];    double *fvec;    double  ftol = REL_SENSOR_TOLERANCE_ftol;    double  xtol = REL_PARAM_TOLERANCE_xtol;    double  gtol = ORTHO_TOLERANCE_gtol;    long     maxfev = MAXFEV;    double  epsfcn = EPSFCN;    double  diag[NPARAMS];    long     mode = MODE;    double  factor = FACTOR;    long     nprint = 0;    long     info;    long     nfev;    double *fjac;    long     ldfjac = m;    long     ipvt[NPARAMS];    double  qtf[NPARAMS];    double  wa1[NPARAMS];    double  wa2[NPARAMS];    double  wa3[NPARAMS];    double *wa4;    /* allocate some workspace */    if (( fvec = (double *) calloc ((unsigned int) m, (unsigned int) sizeof(double))) == NULL ) {       fprintf(stderr,"calloc: Cannot allocate workspace fvec\n");       exit(-1);    }    if (( fjac = (double *) calloc ((unsigned int) m*n, (unsigned int) sizeof(double))) == NULL ) {       fprintf(stderr,"calloc: Cannot allocate workspace fjac\n");       exit(-1);    }    if (( wa4 = (double *) calloc ((unsigned int) m, (unsigned int) sizeof(double))) == NULL ) {       fprintf(stderr,"calloc: Cannot allocate workspace wa4\n");       exit(-1);    }    /* use the current calibration constants as an initial guess */    x[0] = cc.f;    x[1] = cc.Tz;    x[2] = cc.kappa1;    /* define optional scale factors for the parameters */

⌨️ 快捷键说明

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