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

📄 alibratecamera.cpp

📁 用于相机标定的程序。工业测量的一个重要手段是近景摄影测量。其中要用到相机标定。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//相机外参数中的平移参数赋初值
Xs=DLTResult[0];
Ys=DLTResult[1];
Zs=DLTResult[2];
//对fu,fv赋初值


f=(DLTResult[8]+DLTResult[9])/2;
//对u0,v0赋初值

u0=DLTResult[6];
v0=DLTResult[7];
//赋初值
k1=k2=k3=p1=p2=p3=b1=b2=0;

r11=cos(K)*cos(Fi);
r12=-cos(K)*sin(Fi);
r13=sin(K);
r21=sin(W)*sin(K)*cos(Fi)+cos(W)*sin(Fi);
r22=-sin(W)*sin(K)*sin(Fi)+cos(W)*cos(Fi);
r23=-sin(W)*cos(K);
r31=-cos(W)*sin(K)*cos(Fi)+sin(W)*sin(Fi);
r32=cos(W)*sin(K)*sin(Fi)+sin(W)*cos(Fi);
r33=cos(W)*cos(K);
//求定系数阵A
for(j=0;max>0.000000001;j++)
{    
		  for(i=0;i<m;i++)
		  {   
			  r2=pow((ImagePoint[i*2]-u0),2)+pow((ImagePoint[i*2+1]-v0),2);
			 
			 
			  
			  xg=r11*(ControlPoint[i*3]-Xs)+r21*(ControlPoint[i*3+1]-Ys)+r31*(ControlPoint[i*3+2]-Zs);
			  yg=r12*(ControlPoint[i*3]-Xs)+r22*(ControlPoint[i*3+1]-Ys)+r32*(ControlPoint[i*3+2]-Zs);	 
			  zg=r13*(ControlPoint[i*3]-Xs)+r23*(ControlPoint[i*3+1]-Ys)+r33*(ControlPoint[i*3+2]-Zs);
				  
//			  A[2*i*17]=(-fu)/pow(zg,2)*((-r11)*zg+r13*xg);                             //a11系数
//			  A[2*i*17+1]=(-fu)/pow(zg,2)*((-r21)*zg+r23*xg);                           //a12系数
//			  A[2*i*17+2]=(-fu)/pow(zg,2)*((-r31)*zg+r33*xg);                           // a13系数       
//			  A[2*i*17+3]=(-fu)/pow(zg,2)*(zg*((-r31)*(ControlPoint[i*3+1]-Ys)+r21*(ControlPoint[i*3+2]-Zs))-xg*((-r33)*(ControlPoint[i*3+1]-Ys)+r23*(ControlPoint[i*3+2]-Zs)));       //a14系数
//			  A[2*i*17+4]=(-fu)/pow(zg,2)*(    zg*((ControlPoint[i*3]-Xs)*(-sin(K)*cos(Fi)+(ControlPoint[i*3+1]-Ys)*(sin(W)*cos(K)*cos(Fi))+(ControlPoint[i*3+2]-Zs)*(-cos(W)*cos(K)*cos(Fi))))-xg*((ControlPoint[i*3]-Xs)*cos(K)+(ControlPoint[i*3+1]-Ys)*(sin(W)*sin(K))+(ControlPoint[i*3+2]-Zs)*(-cos(W)*sin(K) )  ) );        
//			  A[2*i*17+5]=(-fu)*yg/zg;
			  A[2*i*17+0]=1;
              A[2*i*17+1]=0;
              A[2*i*17+2]=-xg/zg;
              
			  A[2*i*17+3]=-(ImagePoint[i*2]-u0)*r2;
			  A[2*i*17+4]=-(ImagePoint[i*2]-u0)*pow(r2,2);
			  A[2*i*17+5]=-(ImagePoint[i*2]-u0)*pow(r2,2)*r2;
              A[2*i*17+6]=-(r2+2*pow((ImagePoint[i*2]-u0),2));
			  A[2*i*17+7]=-2*(ImagePoint[i*2]-u0)*(ImagePoint[i*2+1]-v0);
		      A[2*i*17+8]=-(ImagePoint[i*2]-u0);
              A[2*i*17+9]=-(ImagePoint[i*2+1]-v0);
			  
			  //A矩阵偶数行进行赋值
//			  A[(2*i+1)*17]=((-fv)/pow(zg,2))*(-r12*zg+r13*yg);  
//			  A[(2*i+1)*17+1]=((-fv)/pow(zg,2))*(-r22*zg+r23*yg); 
//			  A[(2*i+1)*17+2]=((-fv)/pow(zg,2))*(-r32*zg+r33*yg);
//              A[(2*i+1)*17+3]=((-fv)/pow(zg,2))*(zg*(-r32*(ControlPoint[i*3+1]-Ys)+r22*(ControlPoint[i*3+2]-Zs)                       )-yg*((-r33)*(ControlPoint[i*3+1]-Ys)+r23*(ControlPoint[i*3+2]-Zs)                                  )       );
//			  A[(2*i+1)*17+4]=((-fv)/pow(zg,2))*(zg*((ControlPoint[i*3]-Xs)*sin(K)*sin(Fi)+(ControlPoint[i*3+1]-Ys)*(-sin(W))*cos(K)*sin(Fi)+(ControlPoint[i*3+2]-Zs)*cos(W)*cos(K)*sin(K) )-yg*((ControlPoint[i*3]-Xs)*cos(K)+(ControlPoint[i*3+1]-Ys)*sin(W)*sin(K)+(ControlPoint[i*3+2]-Zs)*(-cos(W))*sin(K)));
//			  A[(2*i+1)*17+5]=fv*xg/zg;
              A[(2*i+1)*17+0]=0;
			  A[(2*i+1)*17+1]=1;
			  
			  A[(2*i+1)*17+2]=-yg/zg;
			  A[(2*i+1)*17+3]=-(ImagePoint[i*2+1]-v0)*r2;
			  A[(2*i+1)*17+4]=-(ImagePoint[i*2+1]-v0)*pow(r2,2);
			  A[(2*i+1)*17+5]=-(ImagePoint[i*2+1]-v0)*pow(r2,2)*r2;
			  A[(2*i+1)*17+6]=-2*(ImagePoint[i*2]-u0)*(ImagePoint[i*2+1]-v0);
			  A[(2*i+1)*17+7]=-(r2+2*pow((ImagePoint[i*2+1]-v0),2));
			  A[(2*i+1)*17+8]=0;
			  A[(2*i+1)*17+9]=0;
			  
			  
			 //L矩阵行进行赋值
			  L[2*i]=ImagePoint[i*2]-(  (-f)*xg/zg+u0-(   (ImagePoint[i*2]-u0)*(k1*r2+k2*pow(r2,2)+k3*pow(r2,2)*r2)+p1*(r2+2*pow((ImagePoint[i*2]-u0),2))+2*p2*(ImagePoint[i*2]-u0)*(ImagePoint[i*2+1]-v0)+b1*(ImagePoint[i*2]-u0)+b2*(ImagePoint[i*2+1]-v0) )) ;
			  L[2*i+1]=ImagePoint[i*2+1]-( (-f)*yg/zg+v0-(  (ImagePoint[i*2+1]-v0)*(k1*r2+k2*pow(r2,2)+k3*pow(r2,2)*r2)+p2*(r2+2*pow((ImagePoint[i*2+1]-v0) ,2)  )+2*p1* (ImagePoint[i*2]-u0)*(ImagePoint[i*2+1]-v0)                                              )  );
		 
		  
		  }
		  
		  //参数平差,将平差结果放入s1中
		  adjust.ParameterAdjustment(A,P,L,2*m,10,s1);
		  
          for(int k=0;k<11;k++)
			  s1[k]=-s1[k];

//		  Xs+=s1[0];
//		  Ys+=s1[1];
//		  Zs+=s1[2];
//		  W+=s1[3];
//		  K+=s1[4];
//		  Fi+=s1[5];
		  u0+=s1[0];
		  v0+=s1[1];
		  f+=s1[2];
		  k1+=s1[3];
		  k2+=s1[4];
		  k3+=s1[5];
		  p1+=s1[6];
		  p2+=s1[7];
		  b1+=s1[8];
	      b2+=s1[9];

		  //计算邻近两次结果之差的绝对值,当小于0.000001时停止迭代
		  if(j==0)
		  {
			  for(k=0;k<11;k++)
				  s2[k]=s1[k];
			  
		  } 
		  else 
		  {
			  max=0;
			  for(k=0;k<11;k++)
				  max+=pow((s1[k]-s2[k]),2);
			  
			  
		  }
		  
		  for(k=0;k<11;k++)
			  s2[k]=s1[k];
		  
		  
	  } 



//OutPra[0]=Xs;
//OutPra[1]=Ys;
//OutPra[2]=Zs;
//OutPra[3]=W;
//OutPra[4]=K;
//OutPra[5]=Fi;
//OutPra[6]=u0;
//OutPra[7]=v0;
//OutPra[8]=fu;
//OutPra[9]=fv;
//OutPra[10]=k1;
//OutPra[11]=k2;
//OutPra[12]=k3;
//OutPra[13]=p1;
//OutPra[14]=p2;
//OutPra[15]=b1;
//OutPra[16]=b2;


delete A;
delete L;
delete P ;
delete s1;
delete s2;






















}


/****************通过旋转矩阵计算对应旋转角的弧度***************/
void CalibrateCamera::GetRotAngFromVector(double Vyi, double Vyj, double Vyk, double Vzi, double Vzj, double Vzk, double WKFi[])
{double ang=0;
 const double PI=3.1415926;
     //求rx
    if (fabs(Vzj) < pow(10,-8))							//z轴在当前坐标系的XOZ平面内
	{
		if (Vzk > pow(10,-8))							//z轴与Z轴同向
            ang = 0.0;
        else if (Vzk < -pow(10,-8))						//z轴与Z轴反向
            ang = PI;
        else									//z轴在X轴上
            ang = 0.0;
    }
	else
	{
        if (fabs(Vzk) < pow(10,-8))							//z轴在当前坐标系的XOY平面内
        {
			if (Vzj > 0.0)						//z轴在Y轴正向上
                ang = 3.0 * PI / 2.0;
            else if (Vzj < 0.0)				//z轴在Y轴负向上
                ang = PI / 2.0;
        }
		else									//z轴在一般方向上
		{
			ang = atan(fabs(Vzj / Vzk));
            if ((Vzj<0.0) && (Vzk>0.0))       //z轴在YOZ平面第四象限
                ang = ang;
            else if ((Vzj<0.0) && (Vzk<0.0))  //z轴在YOZ平面第三象限
                ang = PI - ang;
            else if ((Vzj>0.0) && (Vzk<0.0))  //z轴在YOZ平面第二象限
                ang = PI + ang;
            else if ((Vzj>0.0) && (Vzk>0.0))  //z轴在YOZ平面第一象限
                ang = 2.0 * PI - ang;
        }
	}
   double  m_dRx = ang;

	///求ry
    double sxy= sqrt(pow(Vzj,2.0) + pow(Vzk,2.0));
    if (fabs(Vzi) < pow(10,-8))
        ang = 0.0;
    else
	{
        if (sxy < pow(10,-8))                         //z轴在X轴上
        {
			if (Vzi > 0.0)
                ang = PI / 2.0;                 //z轴在X轴正向上
            else
                ang = 3.0 * PI / 2.0;           //z轴在X轴负向上
        }
		else                                    //z轴在一般方向上
        {
			ang = atan(fabs(Vzi / sxy));
            if (Vzi > 0.0)
                ang = ang;
            else
                ang = 2.0 * PI - ang;
		}
	}
   double  m_dRy = ang;
    
    //求rz
    double x2 = Vyi*cos(m_dRy)+Vyj*sin(m_dRx)*sin(m_dRy)
		        -Vyk*cos(m_dRx)*sin(m_dRy);
    double y2 = Vyj*cos(m_dRx)+Vyk*sin(m_dRx);
    double z2 = Vyi*sin(m_dRy)-Vyj*sin(m_dRx)*cos(m_dRy)
		        +Vyk*cos(m_dRx)*cos(m_dRy);

    if (fabs(x2) < pow(10.0,-10.0))  x2 = 0.0;
    if (fabs(y2) < pow(10.0,-10.0))  y2 = 0.0;
    if (fabs(z2) < pow(10.0,-10.0))  z2 = 0.0;

    if (fabs(y2) < pow(10.0,-10.0))
	{
        if (x2 > 0.0)
            ang = 3.0 * PI / 2.0;
        else
            ang = PI / 2.0;
	}
    else
	{
        if (fabs(x2) < pow(10.0,-10.0))
		{
            if (y2 > 0.0)
                ang = 0.0;
            else
                ang = PI;
		}
        else
		{
            ang = atan(fabs(x2 / y2));
            if ((x2 > 0.0) && (y2 > 0.0)) 
                ang = 2.0 * PI - ang;
            else if ((x2 > 0.0) && (y2 < 0.0))
                ang = PI + ang;
            else if ((x2 < 0.0) && (y2 < 0.0))
                ang = PI - ang;
            else if ((x2 < 0.0) && (y2 > 0.0))
                ang = ang;
        }
	}
     double m_dRz = ang;
	while (m_dRx>=2*PI) m_dRx -= 2*PI;
	while (m_dRy>=2*PI) m_dRy -= 2*PI;
	while (m_dRz>=2*PI) m_dRz -= 2*PI;
  WKFi[0]=m_dRx;
  WKFi[1]=m_dRy;
  WKFi[2]=m_dRz;

}

⌨️ 快捷键说明

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