unit SingleCross; {------------------------------------------------- 摄影测量单像空间会方交会算法单元 == ◎◎◎ 作者:陈明(龙在天) ◎◎◎ == == ◎◎◎ 任课老师: 邓 非 ◎◎◎ == QQ:810492306 --------------------------------------------------} interface uses SysUtils,Matrice,PerlRegEx,Classes,Dialogs; type KZPoint=record //地面控制点坐标 X:extended; Y:extended; Z:extended; end; type YXPoint=record //影像点坐标 X:extended; Y:extended; end; type IData=record //三个输入不方便的角度 ψ:extended; ω:extended; κ:extended; end; var m, f, x0, y0, Xs, Ys, Zs:extended; //m,f,x0,y0为内方位元素 PointNum:integer; //控制点的个数 LowLimit:extended; //精度控制 a1, a2, a3, b1, b2, b3, c1, c2, c3:extended; //R矩阵各值 KZPs:array of KZPoint; //用户输入的已知控制点 YXPs:array of YXPoint; //用户输入的已知像点 F3:IData; //三个输入不方便的角度 A,X,L:RCOMat; //平差矩阵, X=[dXs,dYs,dZs,dψ,dω,dκ]T; A[2n,6], L[2n,1] var splitStr:string=' *'; //正则表达式的分隔符 //===========================从文本文件中读取初始数据=========================== procedure DataFromText(filename:string); //===========================初始化数据========================================= procedure InitData; //===========================计算R矩阵========================================== procedure CalcR; //===========================计算L矩阵========================================== procedure CalcL; //===========================计算A矩阵========================================== procedure CalcA; //===========================计算X矩阵========================================== procedure CalcX; //===========================循环计算直到误差够小=============================== procedure Calc; implementation uses Unit1; //===========================从文本文件中读取初始数据=========================== procedure DataFromText(filename:string); var f:TextFile; Reg:TPerlRegEx; s:string; List:TStrings; rows,i:integer; begin Reg:=TPerlRegEx.Create(nil); List:=TStringList.Create; assignfile(f,filename); reset(f); s:=''; rows:=0; while not Eof(f) do begin Readln(f,s); s:=trim(s); //第一行 while s='' do begin readln(f,s); s:=trim(s); end; //处理空行 rows:=rows+1; end; SetLength(KZPs,rows); SetLength(YXPs,rows); PointNum:=rows; Reset(f); for I := 0 to rows - 1 do begin Readln(f,s); s:=Trim(s); while s='' do begin readln(f,s); s:=trim(s); end; reg.Subject := UTF8string(s); reg.RegEx :=UTF8string(splitStr); reg.Split(list,MaxInt); KZPs[i].X:=StrToFloat(List[1]); //Form1.Memo1.Lines.Add(FloatToStr(Kzps[i].X)); KZPs[i].Y:=StrToFloat(List[2]); //Form1.Memo1.Lines.Add(FloatToStr(Kzps[i].Y)); KZPs[i].Z:=StrToFloat(List[3]); //Form1.Memo1.Lines.Add(FloatToStr(Kzps[i].Z)); YXPs[i].X:=StrToFloat(List[4]) / 1000; //Form1.Memo1.Lines.Add(FloatToStr(Yxps[i].X)); YXPs[i].Y:=StrToFloat(List[5]) / 1000; //Form1.Memo1.Lines.Add(FloatToStr(yxps[i].y)); List.Clear; end; Reg.Free; List.Free; CloseFile(f); end; //===========================初始化数据========================================= procedure InitData; var tempX,tempY:extended; I: Integer; begin tempX:=0; tempY:=0; F3.ψ :=0; F3.ω :=0; F3.κ :=0; for I := 0 to PointNum - 1 do begin tempX:=tempX+KZPs[i].X; tempY:=tempX+KZPs[i].Y; end; Zs:=m*f; Xs:=tempX / PointNum; Ys:=tempY / PointNum; end; //===========================计算R矩阵========================================== procedure CalcR; begin a1:=Cos(F3.ψ)*Cos(F3.κ)-Sin(F3.ψ)*Sin(F3.ω)*Sin(F3.κ); a2:=-Cos(F3.ψ)*Sin(f3.κ)-Sin(f3.ψ)*Sin(f3.ω)*Cos(f3.κ); a3:=-Sin(f3.ψ)*Cos(f3.ω); b1:=Cos(f3.ω)*Sin(f3.κ); b2:=Cos(f3.ω)*Cos(f3.κ); b3:=-Sin(f3.ω); c1:=Sin(f3.ψ)*Cos(f3.κ)+Cos(f3.ψ)*Sin(f3.ω)*Sin(f3.κ); c2:=-Sin(f3.ψ)*Sin(f3.κ)+Cos(f3.ψ)*Sin(f3.ω)*Cos(f3.κ); c3:=Cos(f3.ψ)*Cos(f3.ω); end; //===========================计算L矩阵========================================== procedure CalcL; var JSx, JSy:extended; //近似值 I: Integer; begin SetLength(L,2*PointNum,1); //L[2n,1] for I := 0 to PointNum - 1 do begin JSx:=x0/1000-f*( (a1*(KZPs[i].X-Xs) + b1*(KZPs[i].Y-Ys) + c1*(KZPs[i].Z-Zs) ) / ( a3*(KZPs[i].X-Xs) + b3*(KZPs[i].Y-Ys) + c3*(KZPs[i].Z-Zs) ) ); JSy:=y0/1000-f*( (a2*(KZPs[i].X-Xs) + b2*(KZPs[i].Y-Ys) + c2*(KZPs[i].Z-Zs) ) / ( a3*(KZPs[i].X-Xs) + b3*(KZPs[i].Y-Ys) + c3*(KZPs[i].Z-Zs) ) ); L[2*i,0]:=YXPs[i].X-JSx; L[2*i+1,0]:=YXPs[i].Y-JSy; end; end; //===========================计算A矩阵========================================== procedure CalcA; var a11, a12, a13, a21, a22, a23, a14, a15, a16, a24, a25, a26,Z1:extended; i:integer; begin SetLength(A,2*PointNum,6); //A[2n,6] for I := 0 to PointNum - 1 do begin Z1:=a3*(KZPs[i].X-Xs) + b3*(KZPs[i].Y-Ys) + c3*(KZPs[i].Z-Zs); a11:=(a1*f+a3*YXPs[i].X) / Z1; a12:=(b1*f+b3*YXPs[i].X) / Z1; a13:=(c1*f+c3*YXPs[i].X) / Z1; a21:=(a2*f+a3*YXPs[i].Y) / Z1; a22:=(b2*f+b3*YXPs[i].Y) / Z1; a23:=(c2*f+c3*YXPs[i].Y) / Z1; a14:=YXPs[i].Y*Sin(f3.ω)-( (YXPs[i].X*(YXPs[i].X*Cos(f3.κ)-YXPs[i].Y*Sin(f3.κ)))/f+f*Cos(f3.κ) )*Cos(f3.ω); a15:=-f*Sin(f3.κ)-YXPs[i].X*(YXPs[i].X*Sin(f3.κ)+YXPs[i].Y*Cos(f3.κ)) / f; a16:=YXPs[i].Y; a24:=-YXPs[i].X*Sin(f3.ω)-( (YXPs[i].X*(YXPs[i].X*Cos(f3.κ)-YXPs[i].Y*Sin(f3.κ)))/f-f*Sin(f3.κ) )*Cos(f3.ω); a25:=-f*Cos(f3.κ)-YXPs[i].Y*(YXPs[i].X*Sin(f3.κ)+YXPs[i].Y*Cos(f3.κ)) / f; a26:=-YXPs[i].X; A[2*i,0]:=a11; A[2*i,1]:=a12; A[2*i,2]:=a13; A[2*i,3]:=a14; A[2*i,4]:=a15; A[2*i,5]:=a16; A[2*i+1,0]:=a21; A[2*i+1,1]:=a22; A[2*i+1,2]:=a23; A[2*i+1,3]:=a24; A[2*i+1,4]:=a25; A[2*i+1,5]:=a26; end; end; //===========================计算X矩阵========================================== procedure CalcX; var AT,ATA,ATA1,ATA1AT:RCOMat; det:extended; begin InitMat(2*PointNum); SetLength(AT,6,2*PointNum); TransMat(A,AT,2*PointNum,6); //AT=A的转置 SetLength(ATA,6,6); InitMat(6); MatMatR(AT,A,2*PointNum,6,ATA); //ATA[6,6]=AT*A SetLength(ATA1,6,6); InitMat(6); InvMat(ATA,ATA1,det); //ATA1=ATA的逆 SetLength(ATA1AT,6,2*PointNum); InitMat(6); MatMatR(ATA1,AT,6,2*PointNum,ATA1AT);//ATA1AT[6,2*n]=ATA1*AT SetLength(X,6,1); InitMat(6); MatMatR(ATA1AT,L,2*PointNum,1,X); //最后求得X end; //===========================循环计算直到误差够小=============================== procedure Calc; var rs:string; times:integer; begin times:=0; repeat CalcR; CalcL; CalcA; CalcX; Xs:=Xs+X[0,0]; Ys:=Ys+X[1,0]; Zs:=Zs+X[2,0]; f3.ψ:=f3.ψ+X[3,0]; f3.ω:=f3.ω+X[4,0]; f3.κ:=f3.κ+X[5,0]; times:=times+1; Form1.Memo1.Lines.Add('第'+IntToStr(times)+'次迭代============'); Form1.Memo1.Lines.Add('Xs='+FloatToStr(Xs)+';Ys='+FloatToStr(Ys)+';Zs='+FloatToStr(Zs)+';'); Form1.Memo1.Lines.Add('ψ='+FloatToStr(f3.ψ)+';ω='+FloatToStr(f3.ω)+';κ='+FloatToStr(f3.κ)+';'); Form1.Memo1.Lines.Add('dXs='+FloatToStr(X[0,0])+';dYs='+FloatToStr(X[1,0])+';dZs='+FloatToStr(X[2,0])+';dψ='+FloatToStr(X[3,0])+';dω='+FloatToStr(X[4,0])+';dκ='+FloatToStr(X[5,0])); Form1.Memo1.Lines.Add(''); until (abs(X[0,0])<LowLimit) and (abs(X[1,0])<LowLimit) and (abs(X[2,0])<LowLimit) and (abs(X[3,0])<LowLimit) and (abs(X[4,0])<LowLimit) and (abs(X[5,0])<LowLimit); rs:=rs+FloatToStr(Xs)+' '+FloatToStr(Ys)+' '+FloatToStr(Zs)+#13#10; rs:=rs+FloatToStr(f3.ψ)+' '+FloatToStr(f3.ω)+FloatToStr(f3.κ)+#13#10; rs:=rs+IntToStr(times); ShowMessage(rs); end; end.
用法说明:
procedure TForm1.FormCreate(Sender: TObject); begin Form1.Position:=poScreenCenter; DataFromText('data.txt'); m:=50000; f:=0.0281359; x0:=0; y0:=0; LowLimit:=0.000029; InitData; Calc; end;