基于c++和Python的单像空间后方交会

2024-01-27 14:10

本文主要是介绍基于c++和Python的单像空间后方交会,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        学习摄影测量之后一直都很想用代码实现一下这个特别经典的,难度又不是很大的课堂案例,但是由于一直在看其他开源项目的代码,一直被搁置,趁着暑假完成一下曾经的小目标。

        没想到这东西看起来步骤清晰且简单,实现起来竟然踩了特别多的坑,主要就是Python中的数组和基于OpenCV的c++Mat这两者用起来差别有点大,搞得我晕头转向的,很难受......

 一、Python实现:

我先用Python代码实现了一下,毕竟python代码比较......

#空间后方交会
import numpy as np
m = 50000#比例尺分母
limit = 0.0001#迭代限差
def Space_resection(f, X, Y, Z, x, y, H):#初始化x = np.array(x, dtype=np.float32)y = np.array(y, dtype=np.float32)X = np.array(X, dtype=np.float32)Y = np.array(Y, dtype=np.float32)Z = np.array(Z, dtype=np.float32)phi = 0omg = 0kappa = 0Xs = sum(X) / 4Ys = sum(Y) / 4Zs = m * fiteration_num = 50000for i in range(iteration_num):#计算旋转矩阵元素a1 = np.cos(phi) * np.cos(kappa) - np.sin(phi) * np.sin(omg) * np.sin(kappa)a2 = -np.cos(phi) * np.sin(kappa) - np.sin(phi) * np.sin(omg) * np.cos(kappa)a3 = -np.sin(phi) * np.cos(omg)b1 = np.cos(omg) * np.sin(kappa)b2 = np.cos(omg) * np.cos(kappa)b3 = -np.sin(omg)c1 = np.sin(phi) * np.cos(kappa) + np.cos(phi) * np.sin(omg) * np.sin(kappa)c2 = -np.sin(phi) * np.sin(kappa) + np.cos(phi) * np.sin(omg) * np.cos(kappa)c3 = np.cos(phi) * np.cos(omg)R = np.mat([[a1, a2, a3], [b1, b2, b3], [c1, c2, c3]])# print(R)num = len(x)#物点/像点数量# print(num)for j in range(num):#初始化系数矩阵a,常数项矩阵l和近似值x,ya11 = np.zeros(num, dtype=np.float32)a12 = np.zeros(num, dtype=np.float32)a13 = np.zeros(num, dtype=np.float32)a14 = np.zeros(num, dtype=np.float32)a15 = np.zeros(num, dtype=np.float32)a16 = np.zeros(num, dtype=np.float32)a21 = np.zeros(num, dtype=np.float32)a22 = np.zeros(num, dtype=np.float32)a23 = np.zeros(num, dtype=np.float32)a24 = np.zeros(num, dtype=np.float32)a25 = np.zeros(num, dtype=np.float32)a26 = np.zeros(num, dtype=np.float32)l11 = np.zeros(num, dtype=np.float32)l12 = np.zeros(num, dtype=np.float32)appro_x = np.zeros(num, dtype=np.float32)appro_y = np.zeros(num, dtype=np.float32)for j in range(num):#计算每个点的系数矩阵a,常数项矩阵l和近似值x,yappro_x[j] = -f * (a1 * (X[j] - Xs) + b1 * (Y[j] - Ys) + c1 * (Z[j] - Zs)) / (a3 * (X[j] - Xs) + b3 * (Y[j] - Ys) + c3 * (Z[j] - Zs))appro_y[j] = -f * (a2 * (X[j] - Xs) + b2 * (Y[j] - Ys) + c2 * (Z[j] - Zs)) / (a3 * (X[j] - Xs) + b3 * (Y[j] - Ys) + c3 * (Z[j] - Zs))# print(appro_x[j],appro_y[j])a11[j] = -f / Ha12[j] = 0a13[j] = -x[j] / Ha14[j] = -f * (1 + (x[j] * x[j]) / (f * f))a15[j] = -x[j] * y[j] / fa16[j] = y[j]a21[j] = 0a22[j] = -f / Ha23[j] = -y[j] / Ha24[j] = -x[j] * y[j] / fa25[j] = -f * (1 + (y[j] * y[j]) / (f * f))a26[j] = -x[j]#组合A,LA = np.zeros((2 * num, 6), dtype=np.float32)for j in range(num):A[2 * j:2 * j + 2, :] = np.array([[a11[j], a12[j], a13[j], a14[j], a15[j], a16[j]], [a21[j], a22[j], a23[j], a24[j], a25[j], a26[j]]])#print(A)L = np.zeros((2 * num, 1), dtype=np.float32)for j in range(num):L[2 * j:2 * j + 2, :] = np.mat([[x[j] - appro_x[j]], [y[j] - appro_y[j]]])#print(L)#计算ATA,ATL以及改正数X=(ATA)-1(ATL)ATA = np.dot(A.T, A)ATL = np.dot(A.T, L)X_mid = np.dot(np.linalg.inv(ATA), A.T)result = np.dot(X_mid, L)#求新值Xs += result[0,0]Ys += result[1,0]Zs += result[2,0]phi += result[3,0]omg += result[4,0]kappa += result[5,0]if (abs(result[0,0]) < limit and abs(result[1,0]) < limit and abs(result[2,0]) < limit and abs(result[3,0]) < limit and abs(result[4,0]) < limit and abs(result[5,0]) < limit):print("精度满足")return (Xs,Ys,Zs,phi,omg,kappa)else:print(i)print("继续")# print(result)
def main():f = 153.24 / 1000H = f * m#航高x = [-86.15 / 1000, -53.40 / 1000, -14.78 / 1000, 10.46 / 1000]y = [-68.99 / 1000, 82.21 / 1000, -76.63 / 1000, 64.43 / 1000]X = [36589.41, 37631.08, 39100.97, 40426.54]Y = [25273.32, 31324.51, 24934.98, 30319.81]Z = [2195.17, 728.69, 2386.50, 757.31]result = Space_resection(f, X, Y, Z, x, y, H)print(result)
if __name__ == '__main__':main()

运行结果是这样的:

二、c++实现:

#include <iostream>
#include<fstream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
const int m = 50000;//比例尺分母
const double limit = 0.000001;//迭代限差
const int N = 4;//物点/像点个数,根据实际情况修改
const int iteration_num = 50000;//设定的迭代次数
Mat Space_resection(double f, double* x, double* y, double* X, double* Y, double* Z, double H, Mat& result)
{double sumX = 0.0, sumY = 0.0;for (int i = 0; i < N; i++){sumX += *(X + i);}for (int i = 0; i < N; i++){sumY += *(Y + i);}//参数初始化double phi = 0.0, omg = 0.0, kappa = 0.0;double Xs = sumX / 4;double Ys = sumY / 4;double Zs = m * f;for (int times = 1; times <= iteration_num; times++)//开始迭代{//计算旋转矩阵double a1 = cos(phi) * cos(kappa) - sin(phi) * sin(omg) * sin(kappa);double a2 = -cos(phi) * sin(kappa) - sin(phi) * sin(omg) * cos(kappa);double a3 = -sin(phi) * cos(omg);double b1 = cos(omg) * sin(kappa);double b2 = cos(omg) * cos(kappa);double b3 = -sin(omg);double c1 = sin(phi) * cos(kappa) + cos(phi) * sin(omg) * sin(kappa);double c2 = -sin(phi) * sin(kappa) + cos(phi) * sin(omg) * cos(kappa);double c3 = cos(phi) * cos(omg);Mat R = (Mat_<double>(3, 3) << a1, a2, a3, b1, b2, b3, c1, c2, c3);//初始化A,Ldouble appro_x[N] = { 0 };double appro_y[N] = { 0 };double a11[N] = { 0 };double a12[N] = { 0 };double a13[N] = { 0 };double a14[N] = { 0 };double a15[N] = { 0 };double a16[N] = { 0 };double a21[N] = { 0 };double a22[N] = { 0 };double a23[N] = { 0 };double a24[N] = { 0 };double a25[N] = { 0 };double a26[N] = { 0 };double lx[N] = { 0 };double ly[N] = { 0 };//逐点计算A,Lfor (int j = 0; j < N; j++){appro_x[j] = -f * (a1 * (*(X+j) - Xs) + b1 * (*(Y+j) - Ys) + c1 * (*(Z + j) - Zs)) /(a3 * (*(X + j) - Xs) + b3 * (*(Y + j) - Ys) + c3 * (*(Z + j) - Zs));appro_y[j] = -f * (a2 * (*(X + j) - Xs) + b2 * (*(Y + j) - Ys) + c2 * (*(Z + j) - Zs)) /(a3 * (*(X + j) - Xs) + b3 * (*(Y + j) - Ys) + c3 * (*(Z + j) - Zs));lx[j] = *(x + j) - appro_x[j];ly[j] = *(y + j) - appro_y[j];a11[j] = -f / H;a12[j] = 0;a13[j] = -*(x + j) / H;a14[j] = -f * (1 + (*(x + j) *  *(x + j)) / (f * f));a15[j] = -*(x + j) * *(y + j) / f;a16[j] = *(y + j);a21[j] = 0;a22[j] = -f / H;a23[j] = -*(y + j) / H;a24[j] = -*(x + j) * *(y + j) / f;a25[j] = -f * (1 + (*(y + j) * *(y + j)) / (f * f));a26[j] = -*(x + j);}//组合总的A,LMat A(2 * N, 6,CV_64F);Mat L(2 * N, 1, CV_64F);int t = 0, t2 = 0;for (int j = 0; j < 2 * N; j += 2){Mat mid = (Mat_<double>(2, 6) << a11[t], a12[t], a13[t], a14[t], a15[t], a16[t], a21[t], a22[t], a23[t], a24[t], a25[t], a26[t]);for (int row = 0; row < 2; row++){for (int col = 0; col < 6; col++){A.at<double>(row + 2 * t, col) = mid.at<double>(row, col);}}t++;}for (int j = 0; j < 2 * N; j += 2){Mat mid = (Mat_<double>(2, 1) << lx[t2], ly[t2]);for (int row = 0; row < 2; row++){for (int col = 0; col < 1; col++){L.at<double>(row + 2 * t2, col) = mid.at<double>(row, col);}}t2++;}//计算ATA,ATL和XMat ATA = A.t() * A;Mat ATL = A.t() * L;Mat X = (ATA).inv() * A.t()*L;//求新值Xs += X.at<double>(0, 0);Ys += X.at<double>(1, 0);Zs += X.at<double>(2, 0);phi += X.at<double>(3, 0);omg += X.at<double>(4, 0);kappa += X.at<double>(5, 0);//与限差比较if (fabs(X.at<double>(0, 0)) < limit && fabs(X.at<double>(1, 0)) < limit && fabs(X.at<double>(2, 0)) < limit && fabs(X.at<double>(3, 0)) < limit && fabs(X.at<double>(4, 0)) < limit && fabs(X.at<double>(5, 0)) < limit){cout << times << endl;cout << "精度满足";result = (Mat_<double>(6, 1) << Xs, Ys, Zs, phi, omg, kappa);return result;}else{result = (Mat_<double>(6, 1) << X.at<double>(0, 0), X.at<double>(1, 0), X.at<double>(2, 0), X.at<double>(3, 0), X.at<double>(4, 0), X.at<double>(5, 0));}}//return result;
}
int main()
{double f = 153.24 / 1000;double H = f * m;ifstream fin1;ifstream fin2;//从文件中读取物点坐标,像点坐标fin1.open("D:\\Software\\VS2019\\source\\repos\\摄影测量与三维重建\\单片空间后方交会\\像点坐标.txt");fin2.open("D:\\Software\\VS2019\\source\\repos\\摄影测量与三维重建\\单片空间后方交会\\物点坐标.txt");double x[N];double y[N];double X[N];double Y[N];double Z[N];char strx, stry, strX, strY, strZ;fin1 >> strx >> stry;for (int i = 0; i < N; i++){fin1 >> x[i] >> y[i];x[i] /= 1000;y[i] /= 1000;}fin2 >> strX >> strY >> strZ;for (int i = 0; i < N; i++){fin2 >> X[i] >> Y[i] >> Z[i];}Mat result=Mat::zeros(Size(6,1), CV_64F);Mat final_result(6, 1, CV_64F);final_result = Space_resection(f, x, y, X, Y, Z, H, result);cout << final_result;return 0;
}

这个代码要跑起来需要配置OpenCV库,我用的OpenCV里面的Mat,具体配置过程参考这个吧VS配置OpenCV库。

然后就是考虑到这只是一个小案例,实际生产生活中我们有海量的物点和像点,所以我采用了读取文件的方式,这两个文本文件格式如下:

 然后对照着我的代码,应该很容易能看明白。

运行结果如下:和Python的结果差不多,但是就这么一个小程序我都能明显感觉到c++确实比Python运行的快很多。

这篇关于基于c++和Python的单像空间后方交会的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/650472

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)