单像空间后方交会(C语言)


1 原理介绍

1.1 定义

空间后方交会 (Space Resection)的定义:利用地面控制点(GCP,Ground Control Point)及其在像片上的像点,确定单幅影像外方位元素的方法。

如果我们知道每幅影像的6个外方位元素,就能确定被摄物体与航摄影像的关系。因此,如何获取影像的外方位元素,一直是摄影测量工作者所探讨的问题。可采取的方法有:利用雷达、全球定位系统(GPS)、惯性导航系统(INS)以及星相摄影机来获取影像的外方位元素;也可利用影像覆盖范围内一定数量的控制点的空间坐标与影像坐标,根据共线条件方程反求该影像的外方位元素,这种方法称为单幅影像的空间后方交会

1.2 基本思想

以单幅影像为基础,从该影像所覆盖地面范围内的若干控制点的已知地面坐标和相应点的像坐标量测值出发,根据共线条件方程,运用最小二乘间接平差,求解该影像在航空摄影时刻的外方位元素。

在这里插入图片描述

由于共线方程是非线性函数,为了运用最小二乘法,必须先将其线性化。

共线条件方程的线性化

某一点的共线方程为:

在这里插入图片描述在这里插入图片描述

式中,x,y 为这一点的像平面坐标,x0,y0,f 为影像的内方位元素, Xs,Ys,Zs 为摄站点的物方空间坐标, X,Y,Z 为这一点的物方空间坐标。 ai,bi,ci(i=1,2,3) 为影像旋转矩阵的九个元素,即:

在这里插入图片描述
因为未知数是外方位元素,所以将共线方程视为外方位元素的函数。设外方位元素的近似值为

在这里插入图片描述
将共线方程在外方位元素近似值处一阶泰勒展开,得:

在这里插入图片描述在这里插入图片描述

式中 x0,y0 是把外方位元素近似值代入共线方程中得到的 x,y

列出误差方程

将控制点对应的像点的像平面坐标视为观测值,外方位元素视为参数,由共线方程的线性形式可列出误差方程:

在这里插入图片描述在这里插入图片描述

式中 x,y 为控制点对应的像点的像平面坐标,Vx,Vy 为像平面坐标的改正数,
在这里插入图片描述
为参数的改正数。

以上两个方程为一个控制点列出。如果有 n 个控制点,则可以列出 2n 个方程。当 n>=3 时就可求解。

1.3 详细计算

获取已知数据

为了做空间后方交会,需要知道影像比例尺 1/m 、内方位元素 x0,y0,f 、控制点的空间坐标 X,Y,Z ,及其对应像点的像平面坐标 x,y
影像比例尺可以从摄影资料中查取,也可以利用控制点的空间坐标和其对应像点的像平面坐标进行计算。

确定参数初值

参数的初值即 在这里插入图片描述
在竖直航空摄影且地面控制点大体对称分布的情况下,可按如下方法确定初值:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

K0 可在航迹图上找出,或根据控制点坐标通过坐标正反变换求出。

计算旋转矩阵

利用角元素近似值计算方向余弦,组成旋转矩阵 R

在这里插入图片描述

下面列出三个矩阵相乘的结果供计算

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

计算像点坐标近似值

利用参数的近似值,按共线方程计算各个控制点对应像点的像平面坐标近似值

在这里插入图片描述

计算误差方程系数矩阵和常数项

一个控制点对应的误差方程为

在这里插入图片描述在这里插入图片描述

写成矩阵形式为
在这里插入图片描述

其中

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

系数矩阵 A 中的元素均为偏导数。为了计算这些偏导数,引入以下记号:

在这里插入图片描述在这里插入图片描述在这里插入图片描述

由于推导过程较为复杂,此处省略,直接给出结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

对每一个控制点,计算其对应的方程的系数矩阵 Ai 、常数项 Li ,然后联立起来,得:

在这里插入图片描述

记为
在这里插入图片描述

计算法方程系数矩阵和常数项

按最小二乘原理,取权阵为单位阵,则法方程为

在这里插入图片描述

这一步骤需要计算出 ATAATL

求解参数

按下式可求得 X 的值,即外方位元素的改正数

在这里插入图片描述

再将改正数与参数近似值相加,即得后方交会要求解的外方位元素的值。

迭代

通常情况下,按以上步骤求得的外方位元素改正数 X 太大,还不能满足实际需求,因此需要迭代。将第7步解得的外方位元素的值作为新的外方位元素近似值,代入第3步,再次开始计算。如此反复,直至外方位元素改正数 X 小于限差为止。通常对角元素设置限差,即 在这里插入图片描述

1.4 精度评定

按照上述方法求得的外方位元素,其精度可以通过法方程的系数矩阵的逆阵来求得,即
在这里插入图片描述

协因数阵 Q 的对角线上的元素 Qii 就是第 i 个未知数的权倒数。若单位权中误差为 m0 ,则第 i 个未知数的中误差为 [2] 。

在这里插入图片描述

当参加空间后方交会的控制点有 n 个时,单位权中误差可按下式计算:

在这里插入图片描述

2 问题求解

2.1 问题重述

已知摄影机主距 f=153.24mm,四对点的像点坐标与相应的地面点坐标如下表:

控制点号像点x像点y物点X物点Y物点Z
1-0.08615-0.0689936589.4125273.322195.17
2-0.053400.0822137631.0831324.51728.69
3-0.01478-0.0766339100.9724934.982386.50
40.010460.0644340426.5430319.81757.31

计算近似垂直摄影情况下的后方交会解。

2.2 问题解读与说明

1.注意单位的换算mm与m。

2.题目给的条件是近似垂直摄影测量,因此初始角度应该设为0,且应采用简化后的公式,不应画蛇添足(这里为了多做练习,采用未进行简化的式子)。

3.初始Z值的设置应为m*f 而不是简单的求平均值(否则会一直不收敛)。由于m值未给出,参照网上代码选取40000。

4.需要迭代计算的只有六个元素,其余变化皆为六个元素经变换等操作求出,迭代结束限差应先考虑角度,再是Z,最后是XY。

5.注意:这里由于共线方程式进行了简化,将x表示x-x0(这样求出来是零!不知道为什么!因此在求解时根据贡献方程式再一步转化成了-fX/Z和-fY/Z),计算误差公式的A矩阵求解所用的x并不是像点坐标。

6.求逆矩阵采用代数余子式法,利用递归方法,时间复杂度较高,不能用于大数据的计算,LUV分解法相对省时间,但是我不太会= =。动态申请二维数组可以定义长度不定的数组空间,但是定义较为麻烦。

2.3 c语言求解实现代码

/*
---------------------------------------------------------------------
	空间后方交会代码

	时间:2019年11月1日 

	步骤:1.先设置初值
	2.再用间接平差法求得改正值
	3.用改正值加上初始值进行迭代操作,满足限差要求时退出
	4.最后进行精度评价

	参考网址:http://www.docin.com/p-641460791.html
	矩阵求逆 https://cloud.tencent.com/developer/article/1359605
--------------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define GCPNUMBER 4		//设置初始值控制点数量
#define N 6

int main()
{
	int i, j, k;
	int repeatNumber = 0;	//迭代次数
	int m = 40000;	//比例尺
	double x0=0,y0=0,f = 0.15324;	//内方位元素
	double dOuterElem[6] = { 1,1,1,1,1,1 };
	double outerElement[6] = { 0.0 };	//要求的参数:Xs,Ys,Zs,fai,omiga,kaba;
	//输入控制点空间坐标和像坐标xy和XYZ
	double GCPLocationxy [GCPNUMBER][2] = {		//控制点像坐标
		{ -0.08615, -0.06899 },
		{ -0.05340, 0.08221 }, 
		{ -0.01478, -0.07663 }, 
		{ 0.01046, 0.06443 } };	
	double GCPLocationXYZ [GCPNUMBER][3] = {	//控制点物空间坐标
		{ 36589.41, 25273.32, 2195.17 },
		{ 37631.08, 31324.51, 728.69 },
		{ 39100.97, 24934.98, 2386.50 },
		{ 40426.54, 30319.81, 757.31 } };
	printf("单像空间后方交会:\n\n");
	printf("已知条件:\n\n");
	printf("  比例尺:\n      m = %d\n\n", m);
	printf("  内方位元素:\n     x0 = %lf   y0 = %lf   f = %lf\n\n", x0, y0, f);
	printf("  控制点像坐标:\n");
	for (i = 0; i < GCPNUMBER; i++)
	{
		printf("     ");
		for (j = 0; j < 2; j++)
		{
			printf("%lf   ", GCPLocationxy[i][j]);
		}
		printf("\n");
	}
	printf("\n  控制点物空间坐标:\n");
	for (i = 0; i < GCPNUMBER; i++)
	{
		printf("     ");
		for (j = 0; j < 3; j++)
		{
			printf("%lf   ", GCPLocationXYZ[i][j]);
		}
		printf("\n");
	}
	printf("\n迭代过程:");
	//给外方位元素赋初值
	double sumXYZ[3] = { 0.0 };
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < GCPNUMBER; j++)
		{
			sumXYZ[i] += GCPLocationXYZ[j][i];
		}
		for (j = 0; j < 2;j++)
			outerElement[i] = sumXYZ[i] / GCPNUMBER;	//XY为四个控制点取平均值
		outerElement[i] = m*f + sumXYZ[i] / GCPNUMBER;		//Z为m*f
	}

	bool GetMatrixInverse(double **src, int n, double des[N][N]);	//求逆矩阵声明
	do	//迭代过程
	{
		double R[3][3] = { 0.0 };	//旋转矩阵R
		R[0][0] = cos(outerElement[3])*cos(outerElement[5]) - sin(outerElement[3])*sin(outerElement[4])*sin(outerElement[5]);
		R[0][1] = -cos(outerElement[3])*sin(outerElement[5]) - sin(outerElement[3]) * sin(outerElement[4])*cos(outerElement[5]);
		R[0][2] = -sin(outerElement[3])*cos(outerElement[4]);
		R[1][0] = cos(outerElement[4])*sin(outerElement[5]);
		R[1][1] = cos(outerElement[4])*cos(outerElement[5]);
		R[1][2] = -sin(outerElement[4]);
		R[2][0] = sin(outerElement[3])*cos(outerElement[5]) + cos(outerElement[3])*sin(outerElement[4])*sin(outerElement[5]);
		R[2][1] = -sin(outerElement[3])*sin(outerElement[5]) + cos(outerElement[3])*sin(outerElement[4])*cos(outerElement[5]);
		R[2][2] = cos(outerElement[3])*cos(outerElement[4]);

		double Xgang[GCPNUMBER];
		for (i = 0; i < GCPNUMBER; i++)
			Xgang[i] = R[0][0] * (GCPLocationXYZ[i][0] - outerElement[0]) + R[1][0] * (GCPLocationXYZ[i][1] - outerElement[1])
			+ R[2][0] * (GCPLocationXYZ[i][2] - outerElement[2]);
		double Ygang[GCPNUMBER];
		for (i = 0; i < GCPNUMBER; i++)
			Ygang[i] = R[0][1] * (GCPLocationXYZ[i][0] - outerElement[0]) + R[1][1] * (GCPLocationXYZ[i][1] - outerElement[1])
			+ R[2][1] * (GCPLocationXYZ[i][2] - outerElement[2]);
		double Zgang[GCPNUMBER];
		for (i = 0; i < GCPNUMBER; i++)
			Zgang[i] = R[0][2] * (GCPLocationXYZ[i][0] - outerElement[0]) + R[1][2] * (GCPLocationXYZ[i][1] - outerElement[1])
			+ R[2][2] * (GCPLocationXYZ[i][2] - outerElement[2]);
		
		//xy作为初始值,由共线方程式子求得
		double approxxy[GCPNUMBER][2] = { 0.0 };
		for (i = 0; i < GCPNUMBER; i++)
		{
			approxxy[i][0] = -f*Xgang[i] / Zgang[i];
			approxxy[i][1] = -f*Ygang[i] / Zgang[i];
			//用下面的数据求结果等于零,不知道为什么
			//approxxy[i][0] = GCPLocationxy[i][0]-x0;
			//approxxy[i][1] = GCPLocationxy[i][1] - y0;
		}

		//误差方程式元素A
		double A[GCPNUMBER * 2][6];
		for (i = 0; i < GCPNUMBER; i++)
		{
			A[i * 2][0] = (R[0][0] * f + R[0][2] * approxxy[i][0]) / Zgang[i];
			A[i * 2][1] = (R[1][0] * f + R[1][2] * approxxy[i][0]) / Zgang[i];
			A[i * 2][2] = (R[2][0] * f + R[2][2] * approxxy[i][0]) / Zgang[i];
			A[i * 2][3] = (approxxy[i][0] * approxxy[i][1])*R[1][0] / f - (f + pow(approxxy[i][0], 2) / f)*R[1][1] - approxxy[i][1] * R[1][2];
			A[i * 2][4] = -pow(approxxy[i][0], 2)*sin(outerElement[5]) / f - (approxxy[i][0] * approxxy[i][1]) / f*cos(outerElement[5]) - f*sin(outerElement[5]);
			A[i * 2][5] = approxxy[i][1];
			A[i * 2 + 1][0] = (R[0][1] * f + R[0][2] * approxxy[i][1]) / Zgang[i];
			A[i * 2 + 1][1] = (R[1][1] * f + R[1][2] * approxxy[i][1]) / Zgang[i];
			A[i * 2 + 1][2] = (R[2][1] * f + R[2][2] * approxxy[i][1]) / Zgang[i];
			A[i * 2 + 1][3] = -(approxxy[i][0] * approxxy[i][1])*R[1][1] / f + (f + pow(approxxy[i][1], 2) / f)*R[1][0] - approxxy[i][0] * R[1][2];
			A[i * 2 + 1][4] = -pow(approxxy[i][1], 2)*cos(outerElement[5]) / f - (approxxy[i][0] * approxxy[i][1]) / f*cos(outerElement[5]) - f*sin(outerElement[5]);
			A[i * 2 + 1][5] = -approxxy[i][0];
		}
		
		//误差方程式元素L
		double L[GCPNUMBER * 2];
		for (i = 0; i < GCPNUMBER * 2; i++)
		{
			if (i % 2 == 0)	//x
				L[i] = GCPLocationxy[i / 2][0] - approxxy[i / 2][0];
			else
				L[i] = GCPLocationxy[i / 2][1] - approxxy[i / 2][1];
		}
		//求转置
		double AT[6][GCPNUMBER * 2];
		for (i = 0; i < 6; i++)
		{
			for (j = 0; j < GCPNUMBER * 2; j++)
			{
				AT[i][j] = A[j][i];
			}
		}
		//求Naa
		double **Naa=new double*[6];
		//----------------------------动态申请数组-----------------------------
		for(i=0;i<6;i++)
		{
			Naa[i]=new double[6];
		}
		for (int i = 0; i < 6; i++)
		{
			for (int j = 0; j < 6; j++)
			{
				Naa[i][j] = 0.0;
			}
		};
		//-------------------------上面步骤的可以用 double Naa[6][6]={0.0}; 等效替代-----------------
		for (i = 0; i < 6; i++)
		{
			for (j = 0; j < 6; j++)
			{
				for (k = 0; k < GCPNUMBER * 2; k++)
				{
					Naa[i][j] += AT[i][k] * A[k][j];	//计算Naa
				}
			}
		}
		//求Naa逆矩阵
		double NaaInv[6][6] = { 0.0 };
		bool inverse = GetMatrixInverse(Naa, N, NaaInv);

		//求ATL
		double temp[6] = { 0.0 };
		for (i = 0; i < 6; i++)	//行遍历
		{
			for (j = 0; j < GCPNUMBER * 2; j++)
			{
				temp[i] += AT[i][j] * L[j];
			}
		}
		//求三角号
		for (i = 0; i < 6; i++)
		{
			dOuterElem[i] = 0.0;
			for (j = 0; j < 6; j++)
			{
				dOuterElem[i] += NaaInv[i][j] * temp[j];
			}
		}
		//求得迭代后的改正值及迭代后的外方位元素
		printf("\n\n  第%d次迭代改正值:\n     ", ++repeatNumber);
		for (i = 0; i < 6; i++)
		{
			printf("%lf     ", dOuterElem[i]);
			outerElement[i] = outerElement[i] + dOuterElem[i];
		}
		printf("\n  迭代后外方位元素值:\n     ");
		for (i = 0; i < 6; i++)
		{
			printf("%lf     ", outerElement[i]);
		}
	}while (dOuterElem[3] >= 2.908882087e-5 || dOuterElem[4] >= 2.908882087e-5 || dOuterElem[5] >= 2.908882087e-5);//各角元素迭代计算至其改正值小于6秒,6s=2.908882087e-5 弧度。

	//精度评价
	printf("\n\n\n精度评价矩阵:\n");
	//double sum[6] = { 0.0 };
	double outElemAccuracy[6][6] = { 0.0 };
	for (j = 0; j < 6; j++)
	{
		printf("     ");
		for (i = 0; i < 6; i++)
		{
			outElemAccuracy[j][i] = sqrt(abs(dOuterElem[j] * dOuterElem[i]) / double(2 * GCPNUMBER - 6));
			printf("%lf   ", outElemAccuracy[j][i]);
		}
		printf("\n");
	}
	system( "pause" );
}

/*
	以下为求逆矩阵函数:
	方法:代数余子式乘行列式倒数法
	代数余子式用迭代方法完成,行列式也用代数余子式
	按第一行展开计算|A|
	输入要求逆的矩阵和矩阵行列数
*/
double getA(double **arcs , int n)
{
	int i,j,k;
	if (n == 1)
		return arcs[0][0];
	double ans = 0;
	//double temp[N][N] = { 0.0 };
	double **temp=new double *[n-1];
	for(i=0;i<n-1;i++)
	{
		temp[i]=new double[n-1];
	}	
	for (int i = 0; i < n-1; i++)
	{
		for (int j = 0; j < n-1; j++)
		{
			temp[i][j]=0.0;
		}
	}
	for (i = 0; i < n; i++)	//第一行进行遍历
	{
		//其他行列组成矩阵,求代数余子式
		for (j = 0; j < n - 1; j++)
		{
			for (k = 0; k < n - 1; k++)
			{
				temp[j][k] = arcs[j + 1][(k >= i) ? k + 1 : k];
				//printf("%lf  ",temp[j][k]);
			}
		}
		//printf("暂时的------");
		double t = getA(temp, n - 1);

		if (i % 2 == 0)
		{
			ans += arcs[0][i] * t;	//结果:t是代数余子式,arcs【0】【i】是第一行的数字
		}
		else
		{
			ans -= arcs[0][i] * t;
		}
	}
	return ans;
}
//计算每一行每一列的每一个元素所对应的余子式,组成A*
void getAStart(double **arcs, int n, double ans[N][N])
{
	if (n == 1)		//如果是一阶行列式
	{
		ans[0][0] = 1;
		return;
	}
	int i, j, k, t;
	//double temp[N][N];
	double **temp=new double*[N];
	for (i = 0; i<n - 1; i++)
	{
		temp[i] = new double[n - 1];
	}
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = 0; j < n - 1; j++)
		{
			temp[i][j] = 0.0;
		}
	}
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
		{
			//每一个矩阵元素的代数余子式
			for (k = 0; k < n - 1; k++)
			{
				for (t = 0; t < n - 1; t++)
				{
					temp[k][t] = arcs[k >= i ? k + 1 : k][t >= j ? t + 1 : t];
				}
			}
			ans[j][i] = getA(temp, n - 1);
			if ((i + j) % 2 == 1)
			{
				ans[j][i] = -ans[j][i];
			}
		}
	}
	delete temp;
}

//得到给定矩阵src的逆矩阵保存到des中
bool GetMatrixInverse(double **src, int n, double des[N][N])
{
	double flag = getA(src, n);	//|A|
	double t[N][N];
	if (0 == flag)
	{
		printf( "原矩阵行列式为0,无法求逆。请重新运行" );
		return false;
	}
	else
	{
		getAStart(src, n, t);	//求代数余子式
		//求逆矩阵
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				des[i][j] = t[i][j] / flag;
			}
		}
	}
	return true;
}

2.4 程序评价

优点:代码注释全面,输出结果清晰明了,对读代码者较为友好;对于不同的控制点数量只需要更改GCPNUMBER变量即可,无需改变内部函数;用动态申请数组,可以节省部分空间。

缺点:未进行函数的包装,将其过程一股脑扔到了main函数中,显得没有条理;过多使用for循环和数组,感觉程序很臃肿;未进行相似函数的封装(譬如说矩阵乘法)为了省事就直接计算了。

  • 46
    点赞
  • 268
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
### 回答1: 空间后方交会是地图制图中常用的一种方法,它可以通过测量空间位置的参数来确定某一点的地理位置。C语言可以实现空间后方交会,具体步骤如下: 1.确定已知点和未知点的位置及方向,包括已知点的经纬度坐标和高度信息,以及未知点与已知点之间的空间向量方向; 2.利用三角函数计算已知点与未知点之间的距离和高差等信息; 3.根据已知点的方向信息,利用向量运算计算已知点和未知点的大地方位角,即两点之间的方向角度; 4.利用大地方位角和距离信息,以及已知点的经纬度坐标,计算未知点的经纬度坐标; 5.将计算出的未知点的经纬度坐标与高度信息作为结果输出。 C语言实现空间后方交会需要使用数学计算函数库和空间向量运算函数库,例如math.h和vector.h等。在计算过程中需要注意单位的一致性和精度的控制,同时要进行错误处理和异常情况的判断,以保证计算结果的正确性和稳定性。 ### 回答2: 空间后方交会是测量地物位置的重要方法之一,其原理是通过三个测量站的方位角和仰角,计算出目标点的空间坐标。C语言是一种广泛使用的编程语言,可以用来实现空间后方交会计算。具体步骤如下: 1. 定义结构体:为了方便表示点的坐标,可以定义一个名为“POINT”的结构体,包含x、y、z三个成员变量。 2. 输入测站参数:利用scanf函数从键盘输入三个测站的参数,包括测站的位置坐标,以及对于目标点的方位角和仰角。 3. 计算方向余弦矩阵:利用已知方位角和仰角,可以推算出三个测站与目标点间的方向余弦矩阵,表示测站基准系相对于目标点基准系的旋转关系。 4. 计算导航基准系下的坐标:通过方向余弦矩阵,将测站基准系下的坐标转换到导航基准系下,即目标点相对于一个固定的坐标系的坐标。 5. 计算目标点坐标:利用导航基准系下的坐标信息,可以通过简单的向量加减操作计算出目标点的坐标。 6. 输出结果:将计算出的目标点坐标打印到屏幕上,同时也可以输出其他相关参数,如方向余弦矩阵、导航基准系下的坐标等等。 总的来说,C语言实现空间后方交会需要编写一段比较复杂的程序,需要结合数学知识和计算机编程技巧,但是一旦程序编写成功,就可以快速、准确地计算出目标点的坐标,为工程测量和科学研究提供有力的支持。 ### 回答3: 空间后方交会是一种利用多个测量点的位置和方位角来确定一个点位置坐标的方法。在C语言中实现空间后方交会的关键是要掌握三角函数的计算和矩阵运算。 首先,需要建立一个坐标系,确定每个测量点的位置坐标和方位角。然后,通过计算每个测量点到目标点的距离和方位角,可以得到多组空间方位数据。 接下来,可以利用三角函数计算出每个测量点与目标点的夹角以及两点间的距离。然后,可以根据测量点的坐标和与目标点的距离和夹角,来求目标点的坐标。 最后,需要进行矩阵运算来求目标点的位置坐标。通过建立一个方程组,将测量点坐标和目标点坐标之间的关系表示成矩阵形式,就可以用高斯-约旦法进行求。 在C语言中实现空间后方交会需要掌握三角函数、矩阵运算、高斯-约旦法等相关知识。同时,还需要注意精度问题,采用合适的算法和数据类型进行计算,以确保计算结果的精准度和可靠性。
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值