python+gdal+遥感图像拼接(mosaic)的实例


Posted in Python onMarch 10, 2020

作为摄影测量与遥感的从业者,笔者最近开始深入研究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() # 显示出来,不要也可以,但是一般都要了

以上这篇python+gdal+遥感图像拼接(mosaic)的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python读写Excel文件的实例
Nov 01 Python
Python模拟登录12306的方法
Dec 30 Python
pytorch 数据集图片显示方法
Jul 26 Python
在cmder下安装ipython以及环境的搭建
Oct 19 Python
pandas实现to_sql将DataFrame保存到数据库中
Jul 03 Python
Tensorflow模型实现预测或识别单张图片
Jul 19 Python
Python面向对象编程基础实例分析
Jan 17 Python
关于多元线性回归分析——Python&SPSS
Feb 24 Python
win10下opencv-python特定版本手动安装与pip自动安装教程
Mar 05 Python
Django-celery-beat动态添加周期性任务实现过程解析
Nov 26 Python
python正则表达式re.match()匹配多个字符方法的实现
Jan 27 Python
python爬虫之selenium库的安装及使用教程
May 23 Python
python获取栅格点和面值的实现
Mar 10 #Python
Python列表切片常用操作实例解析
Mar 10 #Python
Python numpy多维数组实现原理详解
Mar 10 #Python
python中使用you-get库批量在线下载bilibili视频的教程
Mar 10 #Python
Python字符串hashlib加密模块使用案例
Mar 10 #Python
Python中求对数方法总结
Mar 10 #Python
Python标准库shutil模块使用方法解析
Mar 10 #Python
You might like
PHP.MVC的模板标签系统(三)
2006/09/05 PHP
php中计算程序运行时间的类代码
2012/11/03 PHP
php上传图片并压缩的实现方法
2015/12/22 PHP
详解如何实现Laravel的服务容器的方法示例
2019/04/15 PHP
javascript 密码强度验证规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
2010/05/18 Javascript
jquery入门—选择器实现隔行变色实例代码
2013/01/04 Javascript
jQuery下的动画处理总结
2013/10/10 Javascript
jquery实现显示已选用户
2014/07/21 Javascript
javascript等号运算符使用详解
2015/04/16 Javascript
jQuery实现平滑滚动页面到指定锚点链接的方法
2015/07/15 Javascript
详解AngularJS中的http拦截
2016/02/09 Javascript
Bootstrap进度条组件知识详解
2016/05/01 Javascript
javascript超过容器后显示省略号效果的方法(兼容一行或者多行)
2016/07/14 Javascript
NodeJS创建最简单的HTTP服务器
2017/05/15 NodeJs
node.js + socket.io 实现点对点随机匹配聊天
2017/06/30 Javascript
react路由配置方式详解
2017/08/07 Javascript
解决vue router组件状态刷新消失的问题
2018/08/01 Javascript
jQuery+CSS实现的标签页效果示例【测试可用】
2018/08/14 jQuery
[04:49]2014DOTA2国际邀请赛 Newbee顺利挺进总决赛 ImbaTV独家专访
2014/07/19 DOTA
Python深入学习之闭包
2014/08/31 Python
python实现读Excel写入.txt的方法
2018/04/29 Python
python读取TXT每行,并存到LIST中的方法
2018/10/26 Python
详解利用OpenCV提取图像中的矩形区域(PPT屏幕等)
2019/07/01 Python
pandas 空数据处理方法详解
2019/11/02 Python
python进程池实现的多进程文件夹copy器完整示例
2019/11/27 Python
python中的逆序遍历实例
2019/12/25 Python
jupyter notebook清除输出方式
2020/04/10 Python
Java ExcutorService优雅关闭方式解析
2020/05/30 Python
成人大专生实习期的自我评价
2013/10/02 职场文书
体育活动总结范文
2014/05/04 职场文书
大学社团招新的通讯稿
2014/09/10 职场文书
教书育人演讲稿
2014/09/11 职场文书
青年文明号汇报材料
2014/12/23 职场文书
志愿者事迹材料
2014/12/26 职场文书
go:垃圾回收GC触发条件详解
2021/04/24 Golang
pytorch中的numel函数用法说明
2021/05/13 Python