在使用双线性内插采样法时,需要综合计算被采样点周围四个已知像素点的亮度值。
这种方法的计算较为简单,与最邻近像元法相比具有更好的亮度采样精度,但图像略变模糊。因此双线性内插采样法也是实践中常用的方法。
1.4 纠正结果评价
即通过查阅相关资料和相应的规范,对于进行了几何纠正后的影像结果进行精度评价,如果符合精度的要求,则完成了遥感图像的几何纠正操作。
2 实现方法与过程
1. 利用地面已知控制点求解多项式系数
总体思路是利用最小二乘法求解多项式系数,通过建立误差方程,建立法方程,求解多项式的系数,其中矩阵相关的运算封装在函数里。 //求取变换系数//初始化数组 double POINT[] = { double point[] = { }; //建立矩阵并开辟空间
_Matrix POINTMat(7,6),pointMat(7,2),solveMat(6,2),POINTTMat(6,7); POINTTMat.init_matrix();POINTMat.init_matrix();pointMat.init_matrix(); solveMat.init_matrix(); _Matrix_Calc cal;int i,j,k; //初始化矩阵 k=0;
for (i = 0 ; i < 7;i++) {
for (j = 0 ;j< 6;j++)
{
POINTMat.write(i,j,POINT[k]);
} } k = 0;
for (i = 0;i<7;i++) {
for (j = 0;j<2;j++)
{
k++;
};
pointMat.write(i,j,point[k]);
}
}
cal.transpos(&POINTMat,&POINTTMat);//矩阵求逆
//最小二乘法求矩阵系数,结果存在了solveMat中,为6行二列的矩阵 _Matrix mul1Mat(6,6); mul1Mat.init_matrix();
cal.multiply(&POINTTMat,&POINTMat,&mul1Mat); _Matrix mul2Mat(6,2); mul2Mat.init_matrix();
cal.multiply(&POINTTMat,&pointMat,&mul2Mat); _Matrix invMat(6,6); invMat.init_matrix();
cal.inverse(&mul1Mat,&invMat);
cal.multiply(&invMat,&mul2Mat,&solveMat); 2. 遥感图像的几何纠正变换
首先确定输出地图坐标的边界坐标,通过给出的输入图像左上角端点的坐标值求解出原始图像的各个端点坐标,通过多项式进行转换得到输入地图的端点坐标。
Mat image;
image = imread(\ if(image.empty()) {return;}
getArea(X1,Y1,X2,Y2);//得到输出图像的地理坐标范围 int row,col; row = image.rows; col = image.cols;
//得到输出图像的行列号,已知该图像分辨率为30m int M = (Y2 - Y1)/ 30 + 1; int N = (X2 - X1) / 30 + 1;
unsigned char * im = new unsigned char[M*N];//存储输出图像像素 for(i = 0 ; i < M;i++) {
for(j = 0 ; j k++; } im[i*N + j] = 0; }//先赋值为0 3. 数字图像亮度值重采样 数字图像亮度重采样的方法有很多,这里采用了两种方法。 (1)最邻近像元法,采取距离被采样点最近的像素值作为采样亮度。 for( i = 1 ; i <= M ;i++)//重采样 { for( j = 1 ; j<= N;j++) { double tempX = X1 + (j - 1)*30; double tempY = Y2 - (i - 1)*30; double geo[6] = {1,tempX,tempY,tempX*tempY,tempX*tempX,tempY*tempY}; _Matrix geoMat(1,6); geoMat.init_matrix(); int what; int whatk = 0; for (what = 0 ; what < 6;what++) { geoMat.write(0,what,geo[whatk]); whatk ++; } _Matrix imgMat(1,2); imgMat.init_matrix(); cal.multiply(&geoMat,&solveMat,&imgMat); double imgX = imgMat.arr[0];//原始图像坐标 double imgY = imgMat.arr[1]; int t1 = (int(imgX+0.5) - 800); int t2 = (-(int(imgY+0.5 ) + 3600));//最邻近插值 if(t1 >= 0 &&t1 < col && t2 >= 0 && t2 < row) { im[(i - 1) * N + (j - 1)] = image.data[t1 + t2* col] ; } geoMat.free_matrix(); imgMat.free_matrix(); } } (2)双线性内插法。对被采样点周围的四个像素的亮度值进行双线性内插,具体原理可以用图1所示的三角形线性函数来表示。 for(i=0;i for(j=0;j calculate(&x1,&y1,Xp,Yp,a,b); if(x1>=xa&&x1<=xc && y1>=ya&&y1<=yb){ double r,c; c = x1 - xa; r = yb - y1; double deltax,deltay; deltax = int(r)+1-r; deltay = int(c)+1-c; double Wx1,Wy1,Wx2,Wy2; Wx1 = 1-deltax; Wy1 = 1-deltay; Wx2 = deltax; Wy2 = deltay; int I11,I12,I21,I22; I11 = lpData[nWidth*int(r) + int(c)]; I12 = lpData[nWidth*int(r) + int(c)+1]; I21 = lpData[nWidth*(int(r)+1) + int(c)]; I22 = lpData[nWidth*(int(r)+1) + int(c)+1]; lpRData[N*i + j] = Wx1*Wy1*I11 + Wx2*Wy1*I21 + Wx1*Wy2*I12 + Wx2*Wy2*I22;} } else lpRData[N*i + j] = 0;} 3 软件使用方法 1. 打开Microsoft Visual Studio 2010 软件,新建一个Win32控制台应用程序。 2. 配置相应的OpenCV环境。 首先将OpenCV2.2 文件夹放在与工程根目录平行的目录之下。