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神器对付12306变态验证码
Jan 05 Python
Python简单实现子网掩码转换的方法
Apr 13 Python
详解Python中的文件操作
Aug 28 Python
详解tensorflow训练自己的数据集实现CNN图像分类
Feb 07 Python
flask-restful使用总结
Dec 04 Python
Python数据类型之Set集合实例详解
May 07 Python
Python3实现定时任务的四种方式
Jun 03 Python
PyQt5 在label显示的图片中绘制矩形的方法
Jun 17 Python
Django ModelForm操作及验证方式
Mar 30 Python
Python实现多线程下载脚本的示例代码
Apr 03 Python
使用Python提取文本中含有特定字符串的方法示例
Dec 09 Python
matplotlib源码解析标题实现(窗口标题,标题,子图标题不同之间的差异)
Feb 22 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
用Zend Encode编写开发PHP程序
2006/10/09 PHP
php5编程中的异常处理详细方法介绍
2008/07/29 PHP
php 无限分类的树类代码
2009/12/03 PHP
php获得网站访问统计信息类Compete API用法实例
2015/04/02 PHP
PHP获取网页所有连接的方法(附demo源码下载)
2016/03/30 PHP
一个加密JavaScript的开源工具PACKER2.0.2
2006/11/04 Javascript
10款非常有用的 Ajax 插件分享
2012/03/14 Javascript
js获取class的所有元素
2013/03/28 Javascript
如何让页面加载完成后执行js
2013/06/26 Javascript
jquery获取iframe中的dom对象(两种方法)
2013/07/02 Javascript
jQuery 的全选(全非选)即取得被选中的值使用介绍
2013/11/12 Javascript
禁用Enter键表单自动提交实现代码
2014/05/22 Javascript
JavaScript更改原始对象valueOf的方法
2015/03/19 Javascript
jquery序列化方法实例分析
2015/06/10 Javascript
jQuery EasyUI Pagination实现分页的常用方法
2016/05/21 Javascript
网页中右键功能的实现方法之contextMenu的使用
2017/02/20 Javascript
angularjs实现简单的购物车功能
2017/09/21 Javascript
seajs中最常用的7个功能、配置示例
2017/10/10 Javascript
Gulp实现静态网页模块化的方法详解
2018/01/09 Javascript
了解ESlint和其相关操作小结
2018/05/21 Javascript
python翻译软件实现代码(使用google api完成)
2013/11/26 Python
Python获取文件所在目录和文件名的方法
2017/01/12 Python
浅谈Python中的bs4基础
2018/10/21 Python
Python3.5内置模块之random模块用法实例分析
2019/04/26 Python
pygame编写音乐播放器的实现代码示例
2019/11/19 Python
Django使用django-simple-captcha做验证码的实现示例
2021/01/07 Python
canvas实现飞机打怪兽射击小游戏的示例代码
2018/07/09 HTML / CSS
西尔斯百货官网:Sears
2016/09/06 全球购物
REISS美国官网:伦敦最受欢迎的时尚品牌
2019/08/16 全球购物
Puccini乌克兰:购买行李箱、女士手袋网上商店
2020/08/06 全球购物
政工例会汇报材料
2014/08/26 职场文书
张丽莉观后感
2015/06/16 职场文书
假如给我三天光明读书笔记
2015/06/26 职场文书
2016年习主席讲话学习心得体会
2016/01/20 职场文书
小学思品教学反思
2016/02/20 职场文书
vue如何批量引入组件、注册和使用详解
2021/05/12 Vue.js