python+gdal+遥感图像拼接(mosaic)的实例
作者:爰采麦矣 发布时间:2023-02-22 23:40:34
作为摄影测量与遥感的从业者,笔者最近开始深入研究gdal,为工作打基础!个人觉得gdal也是没有什么技术含量,调用别人的api。但是想想这也是算法应用的一个技能,多学无害!
关于遥感图像的镶嵌,主要分为6大步骤:
step1:
1)对于每一幅图像,计算其行与列;
2)获取左上角X,Y
3)获取像素宽和像素高
4)计算max X 和 min Y,切记像素高是负值
maxX1 = minX1 + (cols1 * pixelWidth)
minY1 = maxY1 + (rows1 * pixelHeight)
step2 :计算输出图像的min X ,max X,min Y,max Y
minX = min(minX1, minX2, …)
maxX = max(maxX1, maxX2, …)
y坐标同理
step3:计算输出图像的行与列
cols = int((maxX – minX) / pixelWidth)
rows = int((maxY – minY) / abs(pixelHeight)
step 4:创建一个输出图像
driver.create()
step 5:
1)计算每幅图像左上角坐标在新图像的偏移值
2)依次读入每幅图像的数据并利用1)计算的偏移值将其写入新图像中
step6 :对于输出图像
1)刷新磁盘并计算统计值
2)设置输出图像的几何和投影信息
3)建立金字塔
下面附上笔者的代码:
#mosica 两张图像
import os, sys, gdal
from gdalconst import *
os.chdir('c:/temp/****')#改变文件夹路径
# 注册gdal(required)
gdal.AllRegister()
# 读入第一幅图像
ds1 = gdal.Open('**.img')
band1 = ds1.GetRasterBand(1)
rows1 = ds1.RasterYSize
cols1 = ds1.RasterXSize
# 获取图像角点坐标
transform1 = ds1.GetGeoTransform()
minX1 = transform1[0]
maxY1 = transform1[3]
pixelWidth1 = transform1[1]
pixelHeight1 = transform1[5]#是负值(important)
maxX1 = minX1 + (cols1 * pixelWidth1)
minY1 = maxY1 + (rows1 * pixelHeight1)
# 读入第二幅图像
ds2 = gdal.Open('**.img')
band2 = ds2.GetRasterBand(1)
rows2 = ds2.RasterYSize
cols2 = ds2.RasterXSize
# 获取图像角点坐标
transform2 = ds2.GetGeoTransform()
minX2 = transform2[0]
maxY2 = transform2[3]
pixelWidth2 = transform2[1]
pixelHeight2 = transform2[5]
maxX2 = minX2 + (cols2 * pixelWidth2)
minY2 = maxY2 + (rows2 * pixelHeight2)
# 获取输出图像坐标
minX = min(minX1, minX2)
maxX = max(maxX1, maxX2)
minY = min(minY1, minY2)
maxY = max(maxY1, maxY2)
#获取输出图像的行与列
cols = int((maxX - minX) / pixelWidth1)
rows = int((maxY - minY) / abs(pixelHeight1))
# 计算图1左上角的偏移值(在输出图像中)
xOffset1 = int((minX1 - minX) / pixelWidth1)
yOffset1 = int((maxY1 - maxY) / pixelHeight1)
# 计算图2左上角的偏移值(在输出图像中)
xOffset2 = int((minX2 - minX) / pixelWidth1)
yOffset2 = int((maxY2 - maxY) / pixelHeight1)
# 创建一个输出图像
driver = ds1.GetDriver()
dsOut = driver.Create('mosiac.img', cols, rows, 1, band1.DataType)#1是bands,默认
bandOut = dsOut.GetRasterBand(1)
# 读图1的数据并将其写到输出图像中
data1 = band1.ReadAsArray(0, 0, cols1, rows1)
bandOut.WriteArray(data1, xOffset1, yOffset1)
#读图2的数据并将其写到输出图像中
data2 = band2.ReadAsArray(0, 0, cols2, rows2)
bandOut.WriteArray(data2, xOffset2, yOffset2)
''' 写图像步骤'''
# 统计数据
bandOut.FlushCache()#刷新磁盘
stats = bandOut.GetStatistics(0, 1)#第一个参数是1的话,是基于金字塔统计,第二个
#第二个参数是1的话:整幅图像重度,不需要统计
# 设置输出图像的几何信息和投影信息
geotransform = [minX, pixelWidth1, 0, maxY, 0, pixelHeight1]
dsOut.SetGeoTransform(geotransform)
dsOut.SetProjection(ds1.GetProjection())
# 建立输出图像的金字塔
gdal.SetConfigOption('HFA_USE_RRD', 'YES')
dsOut.BuildOverviews(overviewlist=[2,4,8,16])#4层
补充知识:运用Python的第三方库:GDAL进行遥感数据的读写
0 背景及配置环境
0.1 背景
GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换和处理。
这个开源栅格空间数据转换库拥有许多和其他语言的接口,对于python,他有对应的第三方包GDAL,下载安装已在上篇文章中提到。
目的: 可以使用Python的第三方包:GDAL进行遥感数据的读写,方便批处理。
0.2 配置环境
电脑系统: win7x64
Python版本: 3.6.4
GDAL版本: 2.3.2
1 读
1.1 TIFF格式
标签图像文件格式(Tag Image File Format,简写为TIFF)是一种灵活的位图格式,主要用来存储包括照片和艺术图在内的图像。它最初由Aldus公司与微软公司一起为PostScript打印开发。TIFF与JPEG和PNG一起成为流行的高位彩色图像格式。
TIFF文件以.tif为扩展名。
def tif_read(tifpath, bandnum):
"""
Use GDAL to read data and transform them into arrays.
:param tifpath:tif文件的路径
:param bandnum:需要读取的波段
:return:该波段的数据,narray格式。len(narray)是行数,len(narray[0])列数
"""
image = gdal.Open(tifpath) # 打开该图像
if image == None:
print(tifpath + "该tif不能打开!")
return
lie = image.RasterXSize # 栅格矩阵的列数
hang = image.RasterYSize # 栅格矩阵的行数
im_bands = image.RasterCount # 波段数
im_proj = image.GetProjection() # 获取投影信息
im_geotrans = image.GetGeoTransform() # 仿射矩阵
print('该tif:{}个行,{}个列,{}层波段, 取出第{}层.'.format(hang, lie, im_bands, bandnum))
band = image.GetRasterBand(bandnum) # Get the information of band num.
band_array = band.ReadAsArray(0,0,lie,hang) # Getting data from zeroth rows and 0 columns
# band_df = pd.DataFrame(band_array)
del image # 减少冗余
return band_array, im_proj, im_geotrans
2 写
2.1 TIFF格式
TIFF格式的数据格式有:Byete、int16、uint16、int32、uint32、float32、float64等7余种。
首先,要判断数据的格式,才能按需求写出。
def tif_write(self, filename, im_data, im_proj, im_geotrans):
"""
gdal数据类型包括
gdal.GDT_Byte,
gdal.GDT_UInt16, gdal.GDT_Int16, gdal.GDT_UInt32, gdal.GDT_Int32,
gdal.GDT_Float32, gdal.GDT_Float64
:param filename: 存出文件名
:param im_data: 输入数据
:param im_proj: 投影信息
:param im_geotrans: 放射变换信息
:return: 0
"""
if 'int8' in im_data.dtype.name: # 判断栅格数据的数据类型
datatype = gdal.GDT_Byte
elif 'int16' in im_data.dtype.name:
datatype = gdal.GDT_UInt16
else:
datatype = gdal.GDT_Float32
# 判读数组维数
if len(im_data.shape) == 3:
im_bands, im_height, im_width = im_data.shape
else:
im_bands, (im_height, im_width) = 1,im_data.shape # 多维或1.2维
#创建文件
driver = 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
3 展示
3.1 TIFF格式
# 这个展示的效果并不是太好,当做示意图用
def tif_display(self,im_data):
"""
:param im_data: 影像数据,narray
:return: 展出影像
"""
# plt.imshow(im_data,'gray') # 必须规定为显示的为什么图像
plt.imshow(im_data) # 必须规定为显示的为什么图像
plt.xticks([]), plt.yticks([]) # 隐藏坐标线
plt.show() # 显示出来,不要也可以,但是一般都要了
来源:https://blog.csdn.net/qq_15642411/article/details/79187787


猜你喜欢
- 本文实例为大家分享了python画条形图的具体代码,供大家参考,具体内容如下在做毕设的过程中有些数据用表格来展现,会很难看出数据之间的差别,
- 如何使用GPU而不是CPU首先查看设备from tensorflow.python.client import device_libprin
- eg:如在后台的标签列表中,实现上移、下移、置顶功能主要实现思路是节点操作,比如说:上移,直接把点击项移动到前一个节点,以此类推,当然实际代
- 今天在给一个img加链接时发现的<body> <a href="#1" >&
- MySQL主从配置及原理,供大家参考,具体内容如下一、环境选择:1.Centos 6.52.MySQL 5.7二、什么是MySQL主从复制M
- 1. 函数式编程概述1.1. 什么是函数式编程?函数式编程使用一系列的函数解决问题。函数仅接受输入并产生输出,不包含任何能影响产生输出的内部
- 每个矿工将从先前创建的交易池中获取交易.要跟踪已挖掘的消息数量,我们必须创建一个全局变量 :last_transaction_index =
- 功能是打开本机端口,映射到指定IP的端口场景1本机:tomcat启动8080,通过本端口工具打开80,指向到tomcat的8080。请求本机
- 在PyTorch中可以方便的验证SoftMax交叉熵损失和对输入梯度的计算关于softmax_cross_entropy求导的过程,可以参考
- 参考官方文档 http://dev.mysql.com/doc/refman/5.7/en/select-into.htmlmysql>
- 篇首语:原来改mdb为asp就能防下载是鬼话。 引子:昨天和animator试验了一下,把data.mdb文件改名为data.as
- 本文代码是使用python抓取京东小米8手机的配置信息首先找到小米8商品的链接:https://item.jd.com/7437788.ht
- 最近在抓取http://skell.sketchengine.eu网页时,发现用requests无法获得网页的全部内容,所以我就用selen
- Python 是一门更注重可读性和效率的语言,尤其是相较于 Java,PHP 以及 C++ 这样的语言,它的这两个优势让其在开发者中大受欢迎
- 代码如下: function HandleTabKey(evt) {
- 生成器定义在Python中,一边循环一边计算的机制,称为生成器:generator。为什么要有生成器列表所有数据都在内存中,如果有海量数据的
- WeTest 导读小程序科普类的文章已经很多了,今天这里讲的是针对小程序的优化方法,可以有效提高小程序的响应速度和用户体验。当然,开发体验也
- 1.前言:将测试数据全部敲入数据库非常繁琐,而且如果与合作伙伴一起开发,部署,那么他们肯定也不想把时间花在一个一个录入数据的繁琐过程中,这时
- 思路改进原博主文章(Python GUI–Tkinter简单实现个性签名设计)的代码,原先的代码是基于Python2的,我这份代码基于Pyt
- 引言最近遭遇了绑定手机号相关的压测需求,有了手机号登录的经验和测试数据,这次算起来比较简单。最重要的是难点就是要求开发配合调整配置已经在上一