原文链接:https://blog.csdn.net/qq_27045589/article/details/81062586

一、几何校正方法

  图像校正本质是建立一种从原始图像行列号到某种投影的数学关系,即实现图像行列坐标到投影坐标的转换。不同的校正方法利用了不同的方法来表示转换关系,但本质上式相同的。常用的几何校正方法包括:几何多项式校正、有理函数模型校正、局部区域校正模型、地理查找表校正等。
  GDAL库中可以实现的校正方法就包括以上四种方法,即:1~3次的几何多项式校正、RPC(有理函数系数)校正、TPS(薄板样条)校正、GeoLoc校正。

二、转换关系的描述

  不同的校正方法需要的信息也不相同,通常我们采用地面控制点(GCPs)的方式来建立转换关系,如果是RPC校正,则需要RPC文件来提供RPC系数。有的卫星数据,例如MODIS是包含GeoLocation Arrays提供每个像素的经纬度,例如Himawari-8卫星数据则直接提供了投影和地理变换参数(仿射变换六参数。

三、Python中的GDAL几何校正

  Python中的几何校正主要靠 gdal.Warp() 函数来实现的,下面说一下主要流程:

1.读取未经校正的图像

  利用 gdal.Open()

from osgeo import gdal
from osgeo import osr dataset = gdal.Open(r'xxx.tif', gdal.GA_Update)

2.构造地面控制点

# 实际控制点肯定要多的多,这里只写了四个点.做成人机交互更好
gcps_list = [gdal.GCP(-111.931075, 41.745836, 0, 1078, 648),
gdal.GCP(-111.901655, 41.749269, 0, 3531, 295),
gdal.GCP(-111.899180, 41.739882, 0, 3722, 1334),
gdal.GCP(-111.930510, 41.728719, 0, 1102, 2548)]

  附控制点构造函数gdal.GCP()的说明

gdal.GCP([x], [y], [z], [pixel], [line], [info], [id])
# x、y、z是控制点对应的投影坐标,默认为0;
# pixel、line是控制点在图像上的列、行位置,默认为0;
# info、id是用于说明控制点的描述和点号的可选字符串,默认为空.

3.添加地面控制点到图像

  在添加之前需要指定一个空间参考,这里以WGS84基准的地理坐标系(经纬度)为例:

sr = osr.SpatialReference()
sr.SetWellKnownGeogCS('WGS84')
# 添加控制点
dataset.SetGCPs(gcps, sr.ExportToWkt())

4.进行校正

  校正就直接调用gdal.Warp()就可以了:

# tps校正 重采样:最邻近法
dst_ds = gdal.Warp(r'xxx_dst.tif', dataset, format='GTiff', tps=True,
xRes=0.05, yRes=0.05, dstNodata=65535, srcNodata=65535,
resampleAlg=gdal.GRIORA_NearestNeighbour, outputType=gdal.GDT_Int32)

  附gdal.Warp()的参数说明:

gdal.Warp(destNameOrDestDS, srcDSOrSrcDSTab, **kwargs)

# destNameOrDestDS --- 输出数据集路径或对象
# srcDSOrSrcDSTab --- 数据集对象或文件名or数据集对象或文件名的数组
# 关键字参数是gdal.WarpOptions()的返回值,或者直接定义gdal.WarpOptions() gdal.WarpOptions(options = [], format = 'GTiff', outputBounds = None,
outputBoundsSRS = one, xRes = None, yRes = None,
targetAlignedPixels = False, width = 0, height = 0, srcSRS = None,
dstSRS = None, srcAlpha = False, dstAlpha = False, warpOptions = None,
errorThreshold = None, warpMemoryLimit = None, creationOptions = None,
outputType = GDT_Unknown, workingType = GDT_Unknown, resampleAlg = None,
srcNodata = None, dstNodata = None, multithread = False, tps = False,
rpc = False, geoloc = False, polynomialOrder = None,
transformerOptions = None, cutlineDSName = None, cutlineLayer = None,
cutlineWhere = None, cutlineSQL = None, cutlineBlend = None,
ropToCutline = False, copyMetadata = True, metadataConflictValue = None,
setColorInterpretation = False, callback = None, callback_data = None):
# options --- 字符串数组, 字符串或者空值
# format --- 输出格式 ("GTiff", etc...)
# outputBounds --- 结果在目标空间参考的边界范围(minX, minY, maxX, maxY)
# outputBoundsSRS --- 结果边界范围的空间参考, 如果在dstSRS中没有指定的话,采用此参数
# xRes, yRes --- 输出分辨率,即像素的大小
# targetAlignedPixels --- 是否强制输出边界是输出分辨率的倍数
# width --- 输出栅格的列数
# height --- 输出栅格的行数
# srcSRS --- 输入数据集的空间参考
# dstSRS --- 输出数据集的空间参考
# srcAlpha --- 是否将输入数据集的最后一个波段作为alpha波段
# dstAlpha --- 是否强制创建输出
# outputType --- 输出栅格的变量类型 (gdal.GDT_Byte, etc...)
# workingType --- working type (gdal.GDT_Byte, etc...)
# warpOptions --- list of warping options
# errorThreshold --- 近似转换的误差阈值(误差像素数目)
# warpMemoryLimit --- 工作内存限制 Bytes
# resampleAlg --- 重采样方法
# creationOptions --- list of creation options
# srcNodata --- 输入栅格的无效值
# dstNodata --- 输出栅格的无效值
# multithread --- 是否多线程和I/O操作
# tps --- 是否使用Thin Plate Spline校正方法
# rpc --- 是否使用RPC校正
# geoloc --- 是否使用地理查找表校正
# polynomialOrder --- 几何多项式校正次数
# transformerOptions --- list of transformer options
# cutlineDSName --- cutline数据集名称
# cutlineLayer --- cutline图层名称
# cutlineWhere --- cutline WHERE 子句
# cutlineSQL --- cutline SQL语句
# cutlineBlend --- cutline blend distance in pixels
# cropToCutline --- 是否使用切割线范围作为输出边界
# copyMetadata --- 是否复制元数据
# metadataConflictValue --- 元数据冲突值
# setColorInterpretation --- 是否强制将输入栅格颜色表给输出栅格
# callback --- 回调函数
# callback_data --- 用于回调的用户数据 # 参数很多,有些也没有试验过,有翻译不对的地方也请批评指正。

  多项式校正和TPS校正经过上述步骤即可实现,分为两种情况:

  • 对于自带GeoLocation元数据段的MODIS数据,利用gdal.Info()查看波段信息,直接利用gdal.Warp()设置geoloc=True后,对目标波段进行校正即可:
ds = gdal.Warp(r'X:\ModisNearest.tif',
r'HDF4_EOS:EOS_SWATH:"X:\MOD021KM.A2018130.0220.061.2018130132414\MOD021KM.A2018130.0220.061.2018130132414.hdf":MODIS_SWATH_Type_L1B:EV_1KM_RefSB',
width=2030, height=1354, format='GTiff', geoloc=True,
dstSRS=sr.ExportToWkt(), resampleAlg=gdal.GRIORA_NearestNeighbour)
  • 对于其他类型数据,则需要构造VRT文件,然后指定geoloc信息 [7],假设现在有一幅未校正图像 XXX.tif,还有 longitude.tif,latitude.tif 两个经纬度文件(写成一个文件也可以,只不过需要改 X_BAND 和 Y_BAND 的值),于是我们构造一个 xxx.vrt 文件,内容如下:
<VRTDataset rasterXSize="60" rasterYSize="39">
<Metadata domain="GEOLOCATION">
<MDI key="SRS">GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AXIS["Lat",NORTH],AXIS["Long",EAST],AUTHORITY["EPSG","4326"]]</MDI>
<MDI key="X_DATASET">X:\longitude.tif</MDI>
<MDI key="X_BAND">1</MDI>
<MDI key="PIXEL_OFFSET">0</MDI>
<MDI key="PIXEL_STEP">1</MDI>
<MDI key="Y_DATASET">X:/latitude.tif</MDI>
<MDI key="Y_BAND">1</MDI>
<MDI key="LINE_OFFSET">0</MDI>
<MDI key="LINE_STEP">1</MDI>
</Metadata>
<VRTRasterBand dataType="Int16" band="1">
<ColorInterp>Gray</ColorInterp>
<NoDataValue>65535</NoDataValue>
<SimpleSource>
<SourceFilename relativeToVRT="1">X:/XXX.tif</SourceFilename>
<SourceBand>3</SourceBand>
<SrcRect xOff="0" yOff="0" xSize="100" ySize="100"/>
<DstRect xOff="0" yOff="0" xSize="100" ySize="100"/>
</SimpleSource>
</VRTRasterBand>
</VRTDataset>

  其中关键的是<Metadata>段中的9个key,其中X_DATASET和Y_DATASET指定了行列对应的经纬度波段,其他标签含义从略,可看参考资料。VRT文件后半部分的<SourceFilename>指定了需要校正的文件。
  有了VRT文件,我们就可以进行校正了,输入改为vrt文件路径,geoloc=True用Warp()校正。

RPC校正

rpc = [ "HEIGHT OFF=l09", "LINE NUM COEFF=-0. 001245683 -0. 09427649 -1. 006342 "
"-1. 954469e-05 0. 001033926 2.020534e-08 -3.845472e-07 一0.002075817 "
"0.0005520694 0 -4.642442e-06 -3.271793e-06 2. 705977e-05 -7.634384e-07 "
"-2.132832e-05 -3.248862e-05 -8.17894e-06 -3.678094e-07 2.002032e-06 "
"3.693162e-08", "LONG OFF=7.1477"
"SAMP DEN COEFF=l " ......]
ds.SetMetadata(rpc,'RPC')
dst_ds = gdal.Warp('output.xxx', ds, dstSRS='EPSG:4326', xRes=0.0002, yRes=0.0002,
rpc=True, transformerOptions = [r'RPC_DEM=X:\DEM.tif'])

Python 利用GDAL对图像进行几何校正的更多相关文章

  1. 利用GDAL实现影像的几何校正

    一.概述 遥感影像和地理坐标进行关联的方式一般有好几种,一种是直接给出了仿射变换系数,即6个參数,左上角地理坐标,纵横方向上的分辨率,以及旋转系数.在这样的情况下,求出某一像素点的地理坐标非常easy ...

  2. 利用多项式实现图像几何校正(Matlab实现)

    1.原理简述:     根据两幅图像中的一些已知对应点(控制点对),建立函数关系式,通过坐标变换,实现失真图像的几何校正. 设两幅图像坐标系统之间畸变关系能用解析式来描述: 根据上述的函数关系,可以依 ...

  3. GDAL利用地理坐标读取图像像元值

    最近的一个项目需要在电子海图中下载已知水深点,导出点的地理坐标(经纬度).然后在arcgis中打开这些地理坐标输出为shp,利用GDAL读取不同波段的点对应的像元值,从而构建水深和像元值的对应关系. ...

  4. ENVI【遥感图像预处理之图像的几何校正】

    ---恢复内容开始--- 一.图像几何校正的概述 1.几何校正方法: 1)利用卫星自带的地理定位文件进行几何校正.主菜单>>>Map>>Georeference传感器的名 ...

  5. 牛!Python 也能实现图像姿态识别溺水行为了!

    作者 | 李秋键 责编 | Carol 封图 | CSDN 下载自视觉中国 众所周知随着人工智能智能的发展,人工智能的落地项目也在变得越来越多,尤其是计算机视觉方面. 很多人学习python,不知道从 ...

  6. [Python] 利用Django进行Web开发系列(二)

    1 编写第一个静态页面——Hello world页面 在上一篇博客<[Python] 利用Django进行Web开发系列(一)>中,我们创建了自己的目录mysite. Step1:创建视图 ...

  7. python利用or在列表解析中调用多个函数.py

    python利用or在列表解析中调用多个函数.py """ python利用or在列表解析中调用多个函数.py 2016年3月15日 05:08:42 codegay & ...

  8. python 利用 ogr 写入shp文件,数据格式

    python 利用 ogr 写入 shp 文件, 定义shp文件中的属性字段(field)的数据格式为: OFTInteger # 整型 OFTIntegerList # 整型list OFTReal ...

  9. Python利用pandas处理Excel数据的应用

    Python利用pandas处理Excel数据的应用   最近迷上了高效处理数据的pandas,其实这个是用来做数据分析的,如果你是做大数据分析和测试的,那么这个是非常的有用的!!但是其实我们平时在做 ...

随机推荐

  1. 8.3考试总结(NOIP模拟19)[最长不下降子序列·完全背包问题·最近公共祖先]

    一定要保护自己的梦想,即使牺牲一切. 前言 把人给考没了... 看出来 T1 是一个周期性的东西了,先是打了一个暴力,想着打完 T2 T3 暴力就回来打.. 然后,就看着 T2 上头了,后来发现是看错 ...

  2. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件

    精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件 内容简介:本文介绍 Spring Boot 的配置文件和配置管理,以及介绍了三种读取配置文 ...

  3. 高效JAVA之用静态工厂方法代替构造器

    程序员这行干的久了,总会染上一些恶习,我就染上一个让人深恶痛绝,自己却津津乐道的习惯,还不想改的那种,它可以叫做强迫症,也可以叫做洁癖.那就是我不允许我的IDEA出现一点点警告,什么黄色背景,绿色波浪 ...

  4. 利用MySQL原数据信息批量转换指定库数据表生成Hive建表语句

    1.写出文件工具类 package ccc.utile; import java.io.*; /** * @author ccc * @version 1.0.0 * @ClassName Write ...

  5. 安装Linux的步骤 包含linux下安装jdk,及mysql

    https://mirrors.tuna.tsinghua.edu.cn/centos/7.9.2009/isos/x86_64/ 镜像下载网址,4G 左右. 安装VMware 15版本 一路下一步, ...

  6. 第2篇-JVM虚拟机这样来调用Java主类的main()方法

    在前一篇 第1篇-关于JVM运行时,开篇说的简单些 中介绍了call_static().call_virtual()等函数的作用,这些函数会调用JavaCalls::call()函数.我们看Java类 ...

  7. Note about Cobertura

    Workflow of Unit Test without Cobertura compile source code; compile test code; run unit test; Workf ...

  8. 树莓派远程连接工具VNC使用教程

    树莓派远程连接工具VNC使用教程 背景故事 树莓派作为一款迷你小主机,大部分的使用场景都会用到远程调试,远程调试用到最多的方式一般就是VNC和SSH,VNC是远程桌面型的远程方式,简单来说就是用Win ...

  9. Git-06-远程仓库

    本地仓库推送到远程仓库 1 创建ssh key 用户主目录下运行如下命令,然后一路回车 ssh-keygen -t rsa -C "1029612787@qq.com" 2 找到公 ...

  10. Golang语言系列-09-接口

    接口 接口的定义和实现 package main import "fmt" /* [接口] 接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现 ...