您的当前位置:首页正文

摄影后方交会0215

2024-01-13 来源:好走旅游网
 摄影测量—空间后方交会

摄影测量单像空间后方交会

10_GIS_2班

已知摄影机主距f=153.24mm,四对点的像点坐标与相应的地面坐标列入下表: 点号 像点坐标 地面坐标 x(mm) y(mm) x(m) y(m) z(m) 1 -86.15 -68.99 36589.41 25273.32 2195.17 2 -53.40 82.21 37631.08 31324.51 728.69 3 -14.78 -76.63 39100.97 24934.98 2386.50 4 10.46 64.43 40426.54 30319.81 757.31 求六个方位元素及其中误差 运用C++编写程序,具体步骤如下图:

首先将原始数据存储到.txt文本下,供后期编程过程中调用

程序代码如下:

// 空间后方交会.cpp : Defines the entry point for the console application. //

#include #include #include #include #include #include

#include \"mtxfunction.h\" //矩阵求逆运算、转置、相乘 using namespace std;

/*************************************** 声明结构类型GCP,用来保存控制点坐标 ***************************************/ struct GCP {

double x; //影像控制点x坐标 double y; //影像控制点y坐标

矿业工程学院_10级GIS_215 - 1 -

摄影测量—空间后方交会

double Xt; //地面控制点Xt坐标 double Yt; //地面控制点Yt坐标 double Zt; //地面控制点Zt坐标 };

/***************************************/ // 声明读取文本数据函数

int Inputdata(int &GCPN, GCP *data, double &m, double &f, double &x0, double &y0);

/***************************************/ //

int main() {

system(\"title 单像空间后方交会\"); //声明变量

int GCPN=100; //控制点对数GCPN

double m =50000, f = 153.24, x0 = 0, y0 = 0; //比例尺m,主距f,外方位元素x0,y0 GCP data[4]; //控制点坐标矩阵

double Xs = 0, Ys = 0, Zs = 0, fai = 0, omiga = 0, k = 0; //内个外方位元素

double mtxX[6]; //X矩阵 X=[ΔXs,ΔYs,ΔZs,Δψ,Δω,Δκ] mtxX[3] = 1;

double mtxR[9]; //旋转矩阵R

double mtxresult1[6][6], mtxresult2[6]; //1保存ATA及其逆矩阵 和2保存ATL,相乘得到X结果

int i, n = 0;

double sum = 0, m0;

/***************************************/ // 读取数据 gotokaishi: ; //goto标记

if(Inputdata(GCPN, data, m, f, x0, y0)) {

cout << \"读取“原始数据.txt”出现错误!\\n\";

cout << \"请将“原始数据.txt”置于程序所在目录中,并检查数据格式。\";

cout << \"\\n数据格式如下所示\\n(第一行为控制点个数和m,第二行为f,x0,y0,其余行为控制点坐标x,y,Xt,Yt,Zt)\\n\"; cout << \"4\0.0\\n\";

cout << \"153.24\0.0\0.0\\n\";

cout << \"-86.15\-68.99\36589.41\25273.32\2195.17\\n\"; cout << \"-53.40\ 82.21\37631.08\31324.51\728.69\\n\"; cout << \"-14.78\-76.63\39100.97\24934.98\2386.50\\n\"; cout << \" 10.46\ 64.43\40426.54\30319.81\757.31\\n\"; cout << \"是否重新读取文件?(Y or N):\"; char ch;

矿业工程学院_10级GIS_215 - 2 -

摄影测量—空间后方交会

cin >> ch;

if('Y' == ch || 'y' == ch) {

system(\"cls\"); goto gotokaishi; }

cout << \"程序即将退出,谢谢使用!\\n\" ; system(\"PAUSE\");

return 0; //读取数据不正确,返回1 }

//计算Xs0,Ys0,Zs0

for(int i = 0; i < GCPN; ++i) {

Xs += data[i].Xt / 4; Ys += data[i].Yt / 4; }

Zs = f * m; arrayXtg; //地面坐标归算后值Xt arrayYtg; //地面坐标归算后值Yt arrayZtg ; //地面坐标归算后值Zt arrayxtg; //影像坐标归算后值xt arrayytg; //影像坐标归算后值yt

double mtxA[2 * 50][6]; //系数矩阵A 4个a11~a16,a21~a26 double mtxAT[6][2 * 50]; //A的转置

double mtxL[2 * 50]; //L矩阵 L=[lx,ly]

cout << \"主距f=\" << f << \"比例尺m=\" << m << endl;

cout << \"像点坐标\\\\" << \"地面点坐标\\n\" << \"x\\\" << \"y\\\" << \"Xt\\\" << \"Yt\\\" << \"Zt\\n\";

for(int i = 0; i < GCPN; ++i) {

cout << data[i].x << \" \" << data[i].y << \" \" << data[i].Xt << \" \" \" \" << data[i].Yt << \" \" << data[i].Zt << endl; }

/***************************************/ // 迭代计算

/***************************************/

while((mtxX[3] > 0.00001 || mtxX[4] > 0.00001 || mtxX[5] > 0.00001) && n < 100) {

矿业工程学院_10级GIS_215 - 3 -

摄影测量—空间后方交会

/*******每次迭代钱将ATA和ATL清空*********/ for(int i = 0; i < 6; ++i) {

for(int j = 0; j < 6; ++j) {

mtxresult1[i][j] = 0; }

mtxresult2[i] = 0; }

++n;//统计迭代次数

cout << \"\\n******************************************\" \"***********************************\"; printf(\"\\n第%d次迭代\\n\

cout << \"Xs=\" << Xs << \"\Ys=\" << Ys << \"\Zs=\" << Zs << \"\\nψ=\" << fai << \"\ω=\" << omiga << \"\κ=\" << k << endl;

////////////****************旋转矩阵R************************/ mtxR[0] = cos(fai) * cos(k) - sin(fai) * sin(omiga) * sin(k); mtxR[1] = -cos(fai) * sin(k) - sin(fai) * sin(omiga) * cos(k); mtxR[2] = -sin(fai) * cos(omiga); mtxR[3] = cos(omiga) * sin(k); mtxR[4] = cos(omiga) * cos(k); mtxR[5] = -sin(omiga);

mtxR[6] = sin(fai) * cos(k) + cos(fai) * sin(omiga) * sin(k); mtxR[7] = -sin(fai) * sin(k) + cos(fai) * sin(omiga) * cos(k); mtxR[8] = cos(fai) * cos(omiga);

printf(\"-------------旋转矩阵R:-----------\\n\");

cout << mtxR[0] << '\' << mtxR[1] << '\' << mtxR[2] << endl; cout << mtxR[3] << '\' << mtxR[4] << '\' << mtxR[5] << endl;

cout << mtxR[6] << '\' << mtxR[7] << '\' << mtxR[8] << endl << endl;

////////////**********************像点坐标计算值************************/

//cout<<\"-------------归算得到控制点坐标------------\\n\";

//cout<<\"Xtg\\"<<\" \" <<\"Ytg\\"<<\" \"<<\"Ztg\\\"<for(int i = 0; i < GCPN; ++i) {

/******************归算控制点坐标************************/

Xtg[i] = mtxR[0] * (data[i].Xt - Xs) + mtxR[3] * (data[i].Yt - Ys) + mtxR[6] *

矿业工程学院_10级GIS_215 - 4 -

摄影测量—空间后方交会

(data[i].Zt - Zs);

Ytg[i] = mtxR[1] * (data[i].Xt - Xs) + mtxR[4] * (data[i].Yt - Ys) + mtxR[7] * (data[i].Zt - Zs);

Ztg[i] = mtxR[2] * (data[i].Xt - Xs) + mtxR[5] * (data[i].Yt - Ys) + mtxR[8] * (data[i].Zt - Zs);

double x_x0, y_y0; //x-x0=-f(X/Z)见书38页(2-5-8) x_x0 = -f * Xtg[i] / Ztg[i]; y_y0 = -f * Ytg[i] / Ztg[i];

/**************计算L矩阵*********************/ mtxL[2 * i] = data[i].x - (x_x0); mtxL[2 * i + 1] = data[i].y - (y_y0);

/*************计算A矩阵**********************/ mtxA[2 * i][0] = (mtxR[0] * f + mtxR[2] * (x_x0)) / Ztg[i]; mtxA[2 * i][1] = (mtxR[3] * f + mtxR[5] * (x_x0)) / Ztg[i]; mtxA[2 * i][2] = (mtxR[6] * f + mtxR[8] * (x_x0)) / Ztg[i];

mtxA[2 * i][3] = (y_y0) * sin(omiga) - (((x_x0) / f) * ((x_x0) * cos(k) - (y_y0) * sin(k)) + f * cos(k)) * cos(omiga);

mtxA[2 * i][4] = -f * sin(k) - ((x_x0) / f) * ((x_x0) * sin(k) + (y_y0) * cos(k)); mtxA[2 * i][5] = (y_y0);

mtxA[2 * i + 1][0] = (mtxR[1] * f + mtxR[2] * (y_y0)) / Ztg[i]; mtxA[2 * i + 1][1] = (mtxR[4] * f + mtxR[5] * (y_y0)) / Ztg[i]; mtxA[2 * i + 1][2] = (mtxR[7] * f + mtxR[8] * (y_y0)) / Ztg[i];

mtxA[2 * i + 1][3] = -(x_x0) * sin(omiga) - (((y_y0) / f) * ((x_x0) * cos(k) - (y_y0) * sin(k)) - f * sin(k)) * cos(omiga);

mtxA[2 * i + 1][4] = -f * cos(k) - ((y_y0) / f) * ((x_x0) * sin(k) + (y_y0) * cos(k)); mtxA[2 * i + 1][5] = -(x_x0); }

/***************输出矩阵A********************/ /* cout<<\"------------矩阵A-------------\\n\"; for(int i=0;i<8;++i) {for(int j=0;j<6;++j) {cout</*************************解法方程*************************/ // 矩阵相关运算在头文件 mtxfunction.h中 // 求A的转置AT

Mxt_ZhuanZhi(&mtxA[0][0], &mtxAT[0][0], 2 * GCPN, 6); // 求A与AT的乘积,保存到mtxresult1矩阵

Mtx_XiangChen(&mtxAT[0][0], &mtxA[0][0], &mtxresult1[0][0], 6, 2 * GCPN, 6); // 求ATA的逆矩阵 Mtx_QiuNi(&mtxresult1[0][0], 6);

矿业工程学院_10级GIS_215 - 5 -

摄影测量—空间后方交会

// 求AT与L的乘积,结果保存到mtxresult2矩阵

Mtx_XiangChen(&mtxAT[0][0], mtxL, &mtxresult2[0], 6, 2 * GCPN, 1); // 求ATA的逆矩阵与ATL的乘积。即X=(ATA)-1 ATL Mtx_XiangChen(*mtxresult1, &mtxresult2[0], &mtxX[0], 6, 6, 1); //Xs=Xs+ΔXs mtxX即X矩阵 Ys,Zs同理 Xs += mtxX[0]; Ys += mtxX[1]; Zs += mtxX[2];

//ψ=ψ+Δψ mtxX即X矩阵 Κ,ω同理 fai += mtxX[3]; omiga += mtxX[4]; k += mtxX[5];

///////////////输出每次迭代计算的改正数////////////////// cout << \"----------改正数--------\\n\" ; for(int i = 0; i < 6; ++i) {

printf(\" mtxX[%d]=%lf\\n\ }

}

/*----------------旋转矩阵R-----------------------*/

mtxR[0] = cos(fai) * cos(k) - sin(fai) * sin(omiga) * sin(k); mtxR[1] = -cos(fai) * sin(k) - sin(fai) * sin(omiga) * cos(k); mtxR[2] = -sin(fai) * cos(omiga); mtxR[3] = cos(omiga) * sin(k); mtxR[4] = cos(omiga) * cos(k); mtxR[5] = -sin(omiga);

mtxR[6] = sin(fai) * cos(k) + cos(fai) * sin(omiga) * sin(k); mtxR[7] = -sin(fai) * sin(k) + cos(fai) * sin(omiga) * cos(k); mtxR[8] = cos(fai) * cos(omiga); //输出结果到文件 FILE *fp_out;

if(!(fp_out = fopen(\"空间后方交会计算结果.txt\错误,结果未能保存到文件\\n\";

/******************输出到文件******************/

fprintf(fp_out, \"\\n----------单像空间后方交会计算程序----------\"); fprintf(fp_out, \"\\n--------------解算完成---------------\");

fprintf(fp_out, \"\\n迭代次数为:%d\\n\ fprintf(fp_out, \"\\n像片外方位元素的解\\n\"); fprintf(fp_out, \"航向顷角ψ=%lf\\\n\

矿业工程学院_10级GIS_215 - 6 -

摄影测量—空间后方交会

fprintf(fp_out, \"旁向倾角ω=%lf\\\n\ fprintf(fp_out, \"像片旋角κ=%lf\\\n\

fprintf(fp_out, \"\Xs=\%lf\\n\Ys=\%lf\\n\Zs=\%lf\\n\ fprintf(fp_out, \"\\n旋转矩阵R:\\n\");

fprintf(fp_out, \"%lf\\%lf\\%lf\\\n\ fprintf(fp_out, \"%lf\\%lf\\%lf\\\n\ fprintf(fp_out, \"%lf\\%lf\\%lf\\\n\ /******************输出到屏幕******************/ cout << \"\\n\\n----------单像空间后方交会计算程序 ----------\"; cout << \"\\n-----------------解算完成 ------------------\"; cout << \"\\n迭代次数为:\" << n << endl; printf(\"\\n像片外方位元素的解\\n\");

cout << \"航向顷角ψ=\\" << fai << endl; cout << \"旁向倾角ω=\\" << omiga << endl; cout << \"像片旋角κ=\\" << k << endl;

printf(\"\Xs=\%lf\\n\Ys=\%lf\\n\Zs=\%lf\\n\ cout << endl;

printf(\"旋转矩阵R:\\n\");

cout << mtxR[0] << '\' << mtxR[1] << '\' << mtxR[2] << endl; cout << mtxR[3] << '\' << mtxR[4] << '\' << mtxR[5] << endl;

cout << mtxR[6] << '\' << mtxR[7] << '\' << mtxR[8] << endl << endl; /**************计算单位权中误差m0*******************/ for(i = 0; i < 2 * GCPN; i++) sum += pow(mtxL[i], 2); m0 = sqrt(sum / (2 * GCPN - 6));

/******************输出到文件******************/ fprintf(fp_out, \"\\n单位权中误差m0=%lf\\n\ fprintf(fp_out, \"\\n六个外方位元素精度:\\n\");

fprintf(fp_out, \"Xs的精度为:\%lf米\\n\ fprintf(fp_out, \"Ys的精度为:\%lf米\\n\ fprintf(fp_out, \"Zs的精度为:\%lf米\\n\ fprintf(fp_out, \" ψ的精度为:\%lf秒\\n\ fprintf(fp_out, \" ω的精度为:\%lf秒\\n\ fprintf(fp_out, \" κ的精度为:\%lf秒\\n\ fprintf(fp_out, \"\\n\\n----------解算完成----------\" \"-------------------------\");

/******************输出到屏幕******************/ cout << \"单位权中误差m0=\" << m0 << endl; cout << \"六个外方位元素精度:\" << endl;

cout << \"Xs的精度为:\\" << m0 *sqrt(mtxresult1[0][0]) << \"米\" << endl; cout << \"Ys的精度为:\\" << m0 *sqrt(mtxresult1[1][1]) << \"米\" << endl; cout << \"Zs的精度为:\\" << m0 *sqrt(mtxresult1[2][2]) << \"米\" << endl;

矿业工程学院_10级GIS_215 - 7 -

摄影测量—空间后方交会

cout << \"ψ的精度为:\\" << m0 *sqrt(mtxresult1[3][3]) << \"秒\" << endl; cout << \"ω的精度为:\\" << m0 *sqrt(mtxresult1[4][4]) << \"秒\" << endl; cout << \"κ的精度为:\\" << m0 *sqrt(mtxresult1[5][5]) << \"秒\" << endl; cout << \"\\n\\n----------解算完成----------\\n\"; fclose(fp_out); fp_out = NULL;

MessageBox(NULL, \"解算完成,点击确定打开结果保存文件!\空间后方交会\

system(\"空间后方交会计算结果.txt\"); //system(\"PAUSE\"); return 0; }

/****************************************/

// GCPN是控制点对数,data用来保存控制点数据,m是比例尺,f,x0,y0是内方位元素 // 从程序所在文件夹读取“原始数据.txt\"

int Inputdata(int &GCPN, GCP *data, double &m, double &f, double &x0, double &y0) {

FILE *fp_data;

if(!(fp_data = fopen(\"D:\\\\原始数据.txt\ {

return 1; //如果文件读取失败,返回1 }

cout << \"读取到的数据为\\n\";

fscanf(fp_data, \"%d%lf\ cout << \"控制点个数:\" << GCPN << endl; cout << \"航摄比例尺:\" << m << endl; if(GCPN < 4) {

return 2; //控制点低于4个(不足),返回2 }

fscanf(fp_data, \"%lf%lf%lf\ f /= 1000; //毫米单位换算为米

cout << \"主距f=\" << f << \"\x0=\" << x0 << \"\y0=\" << y0 << endl; if(m < 0 || f < 0) {

return 3; //如果m<0或f<0,则返回3,即文本文件格式不对 }

// data = new GCP [GCPN]; //分配控制点对数个GCP类型空间 // cout<<\"像点坐标\\\\"<<\"地面点坐标\\n\"<<\"x\\\"<<\"y\\\"<<\"Xt\\\"<<\"Yt\\\"<<\"Zt\\n\"; for(int i = 0; i < GCPN; ++i) {

if(fscanf(fp_data, \"%lf%lf%lf%lf%lf\

矿业工程学院_10级GIS_215 - 8 -

摄影测量—空间后方交会

&data[i].Zt) != 5) {

return 3; //每对控制点5个数据不足,返回3 }

data[i].x /= 1000;

data[i].y /= 1000; //换算为米

//

cout<}

/****************************************************/ // 如果比例尺为0,那么就用控制点计算比例尺

if(m == 0) {

double image_d, ground_d, temp1, temp2, temp3;

temp1 = pow(data[0].x - data[1].x, 2) + pow(data[0].y - data[1].y, 2); temp2 = pow(data[2].y - data[3].y, 2) + pow(data[2].y - data[3].y, 2); temp3 = pow(data[1].y - data[2].y, 2) + pow(data[1].y - data[2].y, 2); image_d = sqrt(temp1) + sqrt(temp2) + sqrt(temp3);

temp1 = pow(data[0].Xt - data[1].Xt, 2) + pow(data[0].Yt - data[1].Yt, 2); temp2 = pow(data[2].Xt - data[3].Xt, 2) + pow(data[2].Yt - data[3].Yt, 2); temp3 = pow(data[1].Xt - data[2].Xt, 2) + pow(data[1].Yt - data[2].Yt, 2); ground_d = sqrt(temp1) + sqrt(temp2) + sqrt(temp3);

m = 1 / (image_d / ground_d);

cout << \"计算得到比例尺:\" << m << endl; }

fclose(fp_data); fp_data = NULL;

return 0; //一切顺利,返回0 }

结果截图:

矿业工程学院_10级GIS_215 - 9 -

摄影测量—空间后方交会

矿业工程学院_10级GIS_215 - 10 -

因篇幅问题不能全部显示,请点此查看更多更全内容