当前位置: 首页 > news >正文

Python将普通图像转化为栅格影像

引言

本人研究的方向是遥感,研究了2年也搞没清楚普通图像和遥感影像的区别,只知道到了多了地理坐标信息,但是经纬度信息映射到每个图像像素点的底层逻辑我还不太理解。因为现在需要使用python将图像转化为栅格影像,所以在此仔细研究一下。

地理坐标系和投影坐标系

【精选】地理坐标系VS投影坐标系_cgcs2000_3_degree_gk_cm_105e和gcs_china_geodetic_co ...

做遥感首先要理解地理坐标系(GeographicCoordinate System)和投影坐标系(ProjectedCoordinate System)2个概念。

  • 地理坐标系是球面坐标,参考平面是椭球面,坐标单位是经纬度;

  • 投影坐标系是平面坐标系,参考平面是水平面,坐标单位是米、千米等。

  • 地理坐标系转换到投影坐标系的过程理解为投影,即将不规则的地球曲面转换为平面。

img

以一个具体示例来初识ArcGIS中的坐标系,其全部参数拷贝在下面。这一示例是一个“投影坐标系(Projected Coordinate System)”。其名称是“WGS_1984_UTM_Zone_50N”。“WKID”是坐标系的编号,“ESPG”是“European Petroleum Survey Group”的缩写,表示其由“欧洲石油调查组织”发布。

可知,“WGS_1984_UTM_Zone_50N”这个投影坐标系由两部分组成:名为“Transverse_Mercator”的“投影(Projection)”和名为“GCS_WGS_1984”的“地理坐标系(GeographicCoordinate System)”。

WGS_1984_UTM_Zone_50N
WKID: 32650Authority: EPSG
Projection:Transverse_Mercator
False_Easting:500000.0
False_Northing:0.0
Central_Meridian:117.0
Scale_Factor:0.9996
Latitude_Of_Origin:0.0
Linear Unit: Meter(1.0)
GeographicCoordinate System: GCS_WGS_1984
Angular Unit:Degree (0.0174532925199433)
Prime Meridian:Greenwich (0.0)
Datum: D_WGS_1984
Spheroid: WGS_1984
Semimajor Axis: 6378137.0
Semiminor Axis: 6356752.314245179
Inverse Flattening: 298.257223563

地理坐标系

地理坐标系由三个参数来定义:角度单位(Angular Unit)、本初子午线(Prime Meridian)和大地测量系统(Datum)。

地理坐标系“GCS_WGS_1984”使用的角度单位为“度(Degree)”,0.0174532925199433这个数字等于“π/180”,使用的本初子午线为0.0度经线,即格林威治皇家天文台(Greenwich)所在位置的经线,使用的大地测量系统则为“D_WGS_1984”。
**地理坐标系的最重要的参数是“大地测量系统(Datum)”,而大地测量系统的最重要的参数是“椭球(Spheroid)”。**椭球相同,大地测量系统不一定相同,因为原点(origin)和方位(orientation)可以不同。想象一下,同一个椭球,首先可以固定在三维空间中的任意一个点,并且在固定于某点后还能以三个自由度任意地旋转其方位(朝向)。

WGS_1984”椭球的“长半轴(Semimajor Axis)”和“短半轴(Semiminor Axis)”分别为6378137.0和6356752.314245179,其“反扁率(Inverse Flattening)”为298.257223563,等于Semimajor Axis/( Semimajor Axis - Semiminor Axis)。

投影坐标系“WGS_1984_UTM_Zone_50N”使用的“投影(Projection)”名为“横轴墨卡托(Transverse_Mercator)”,然而这个名称并不能完全准确概括其投影。

投影坐标系

事实上,投影坐标系“WGS_1984_UTM_Zone_50N”这个名称中的“WGS_1984”指出了其地理坐标系为“GCS_WGS_1984”,而“UTM_Zone_50N”则指出了其投影。

“UTM_Zone_50N”这个名称指出,其投影方法是“通用横轴墨卡托(Universal Transverse Mercator,UTM)”,其投影带为北半球第50带,这个“Zone_50N”的“中央经线(Central Meridian)”正是117.0度,在“Transverse_Mercator”的参数中得到了体现。举一反三,“Xian_1980_GK_CM_117E”这个坐标系使用的地理坐标系为“GCS_Xian_1980”,而投影名称“GK_CM_117E”指出其使用以东经117度为中央经线的“高斯-克吕格(Gauss-Kruger,GK)”投影。投影的另一个重要参数是“东偏(False Easting)”。

有些投影会在X坐标值前加上投影带号,比如:“Xian_1980_GK_Zone_20”的“false_easting”参数为20500000.0,其中20为投影带号,而“Xian_1980_GK_CM_117E”的“false_easting”参数为500000.0,尽管它们的中央经线都为东经117度。

地理坐标系和投影坐标区别及常用操作: https://zhuanlan.zhihu.com/p/484585670

GeoTIFF数据格式

GeoTIFF是一种常用的地理信息系统(GIS)数据格式,它结合了TIFF(Tagged Image File Format)图像格式和地理空间信息。GeoTIFF文件可以包含地理坐标系、投影信息、地理位置和其他与地理空间数据相关的元数据。

GeoTIFF文件可以存储各种类型的地理空间数据,包括栅格数据(如卫星影像、数字高程模型等)和矢量数据(如点、线、面等地理要素)。它支持不同的地理坐标系和投影系统,可以准确地表示地球上的位置和形状。

GeoTIFF文件的优点包括:

  1. 与TIFF格式兼容:GeoTIFF文件可以使用标准的TIFF查看器和编辑器打开和编辑。
  2. 地理空间信息:GeoTIFF文件可以包含地理坐标系、投影信息和其他与地理空间数据相关的元数据,使得数据可以准确地在地球上的位置上显示和分析。
  3. 多波段支持:GeoTIFF文件可以存储多个波段的数据,例如多光谱卫星影像,方便进行多光谱分析。
  4. 跨平台兼容性:GeoTIFF文件可以在不同的GIS软件和平台上使用,包括ArcGIS、QGIS、ENVI等。

使用GeoTIFF文件,可以进行地理空间数据的获取、处理、分析和可视化,是GIS领域中常用的数据格式之一。

以下是一些常见的地理空间信息在GeoTIFF文件中的保存方式:

  1. 坐标系信息:GeoTIFF文件中保存了坐标系的相关信息,包括坐标系的名称、投影信息、椭球体参数等。这些信息可以通过GeoTIFF文件的元数据标签来获取。
  2. 地理范围:GeoTIFF文件可以保存地理范围的信息,即图像所覆盖的地理区域的边界。通常使用左上角和右下角的经纬度坐标来表示地理范围。
  3. 分辨率:GeoTIFF文件可以保存图像的分辨率信息,即每个像素代表的地理距离。通常以米或度为单位。
  4. 像素对应的地理坐标:GeoTIFF文件可以保存每个像素对应的地理坐标信息。这样可以通过像素坐标来获取对应的地理位置。

这些地理空间信息是通过GeoTIFF文件的元数据标签来保存的,常见的元数据标签包括"GeoKeyDirectoryTag"、“ModelPixelScaleTag”、"ModelTiepointTag"等。可以使用专门的GIS软件或者Python库(如GDAL)来读取和处理GeoTIFF文件的地理空间信息。

GDAL库

GDAL 官方文档 (osgeo.cn)

GDAL(Geospatial Data Abstraction Library)是一个开源的地理空间数据处理库,它提供了对各种格式的地理空间数据进行读取、写入和转换的功能。GDAL库支持包括GeoTIFF、Shapefile、NetCDF、HDF等在内的多种地理空间数据格式。

GDAL库的主要功能包括:

  1. 数据读取和写入:GDAL可以读取和写入各种地理空间数据格式,包括栅格数据和矢量数据。它可以从文件、数据库或内存中读取数据,并将数据写入到文件或其他数据源中。

  2. 数据转换和投影:GDAL可以进行地理空间数据的投影转换、坐标系转换和数据格式转换。它提供了丰富的投影和坐标系操作功能,可以将数据从一个坐标系转换到另一个坐标系,并进行投影变换。

  3. 数据操作和分析:GDAL提供了一些基本的数据操作和分析功能,如裁剪、重采样、统计等。它可以对栅格数据进行像素级别的操作,如计算均值、最大值、最小值等。

  4. 数据集信息获取:GDAL可以获取地理空间数据集的元数据信息,包括坐标系信息、地理范围、分辨率等。它还可以获取数据集中的波段信息、属性表信息等。

GDAL是一个功能强大且广泛应用的地理空间数据处理库,它提供了丰富的功能和灵活的接口,适用于各种地理空间数据处理需求。在Python中,可以使用GDAL库的Python绑定(即GDAL Python)来进行地理空间数据处理。

基础操作

from osgeo import gdal# 打开影像文件
dataset = gdal.Open('data/other/guoyang2019.tif')
# 获取影像宽度和高度
width = dataset.RasterXSize
height = dataset.RasterYSize
# 获取影像波段数
band_count = dataset.RasterCount
# 获取投影信息
projection = dataset.GetProjection()
# 获取地理转换信息
geotransform = dataset.GetGeoTransform()
# 打印影像基本信息
print("影像宽度:", width)
print("影像高度:", height)
print("波段数:", band_count)
print("投影信息:", projection)
print("地理转换信息:", geotransform)
# 关闭影像文件
dataset = None

输出:

影像宽度: 7471
影像高度: 4896
波段数: 1
投影信息: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
地理转换信息: (115.878317255137, 8.982254799999953e-05, 0.0, 33.785346925021, 0.0, -8.982254799999988e-05)

其中地理转换信息即仿射矩阵,实现了从像素点到经纬度坐标的变换,其含义为

GeoTransform = [115.878317255137, 8.982254799999953e-05, 0.0, 33.785346925021, 0.0, -8.982254799999988e-05]
'''
0:图像左上角的X坐标;
1:图像东西方向分辨率;
2:旋转角度,如果图像北方朝上,该值为0;
3:图像左上角的Y坐标;
4:旋转角度,如果图像北方朝上,该值为0;
5:图像南北方向分辨率;
'''
得到这六个参数之后就可以进行图像像素坐标(即行列号)和地理坐标之间的变换:
#像素坐标和地理坐标仿射变换
XGeo = GeoTransform[0]+GeoTransform[1]*Xpixel+Ypixel*GeoTransform[2];
YGeo = GeoTransform[3]+GeoTransform[4]*Xpixel+Ypixel*GeoTransform[5];

读取和写入文件的函数:

def read_img(filename):dataset = gdal.Open(filename)im_width = dataset.RasterXSize #栅格矩阵的列数im_height = dataset.RasterYSize #栅格矩阵的行数im_geotrans = dataset.GetGeoTransform() #仿射矩阵im_proj = dataset.GetProjection() #地图投影im_data = dataset.ReadAsArray(0,0,im_width,im_height)del datasetreturn im_proj,im_geotrans,im_data
def write_img(filename,im_proj,im_geotrans,im_data):if "int8" in im_data.dtype.name:datatype = gdal.GDT_Byteif "int16" in im_data.dtype.name:datatype = gdal.GDT_UInt16else:datatype = gdal.GDT_Float32if len(im_data.shape) == 3:im_bands, im_height, im_width = im_data.shapeelse:im_bands, (im_height, im_width) = 1, im_data.shapedriver = gdal.GetDriverByName("GTiff")  # 数据类型必须有,因为要计算需要多大内存空间dataset = driver.Create(filename, im_width, im_height, im_bands, datatype)dataset.SetGeoTransform(im_geotrans)  # 写入仿射变换参数dataset.SetProjection(im_proj)  # 写入投影if im_bands == 1:dataset.GetRasterBand(1).WriteArray(im_data)  # 写入数组数据else:for i in range(im_bands):dataset.GetRasterBand(i + 1).WriteArray(im_data[i])del dataset

实战

写这篇文章的目的是因为我目前深度学习拼接上的作物分布图只是一张PNG图片,没有地理坐标信息,现在需要通过代码添加上:

SoyaMap

from osgeo import gdal, osrpath = f"img/predict2020/SoyaMap.png"
# 读取图像
image = Image.open(path)
# 转换为numpy数组
image_array = (1-np.array(image)/255).astype(np.int8)
# 创建一个空间参考对象 ,将空间坐标系设置为EPSG:4326
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
# 地理转换信息,图像左上角的经纬度坐标点和像素大小
geotransform = [115.86991557438377,8.983152841195215E-5, 0.0, 33.789500591456914, 0.0, -8.983152841195215E-5]
write_img("img/predict2020/SoyaMap.tif",srs.ExportToWkt(),geotransform,image_array)

导出成功后,使用Arcgis打开制图,简直不要太酷啦。

涡阳大豆分布图2020

相关文章:

  • python3遇到Can‘t connect to HTTPS URL because the SSL module is not available.
  • m3u8网络视频文件下载方法
  • HDMI2.1输入转4Port MIPI/LVDS输出,嵌入式SPI闪存固件存储,VR和AR应用首选国产芯片方案-LT6911GXC
  • 设计模式——行为型模式
  • 成为一名FPGA工程师:面试题与经验分享
  • 智慧园区物联综合管理平台感知对象管理能力简述
  • JavaScript:函数隐含对象arguments/剩余参数. . .c/解构赋值
  • javafx写一个文档编辑器
  • Unity中Shader裁剪空间推导(在Shader中使用)
  • 2024最新前端React面试题:React18相比react17有哪些主要更新?
  • 了解英语中主语谓语宾语等等句子成分
  • 共享单车之数据存储
  • Linux命令的操作练习
  • 华为OD机试真题-最小矩阵宽度-2023年OD统一考试(C卷
  • 西北工业大学计算机组成原理实验报告——verilog后两次
  • 网络传输文件的问题
  • @jsonView过滤属性
  • Docker 笔记(2):Dockerfile
  • ECS应用管理最佳实践
  • Git 使用集
  • golang 发送GET和POST示例
  • JavaScript 基本功--面试宝典
  • Javascript基础之Array数组API
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Spring Cloud Feign的两种使用姿势
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 力扣(LeetCode)56
  • 使用API自动生成工具优化前端工作流
  • 微信开放平台全网发布【失败】的几点排查方法
  • 怎么把视频里的音乐提取出来
  • - 转 Ext2.0 form使用实例
  • 转载:[译] 内容加速黑科技趣谈
  • 《码出高效》学习笔记与书中错误记录
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • ​VRRP 虚拟路由冗余协议(华为)
  • #pragma data_seg 共享数据区(转)
  • #QT(TCP网络编程-服务端)
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (规划)24届春招和25届暑假实习路线准备规划
  • (五)IO流之ByteArrayInput/OutputStream
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .jks文件(JAVA KeyStore)
  • .net core 控制台应用程序读取配置文件app.config
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .net core开源商城系统源码,支持可视化布局小程序
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .NET/C# 使用反射注册事件
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .NET业务框架的构建
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • @Not - Empty-Null-Blank
  • [@Controller]4 详解@ModelAttribute