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 Deque 模块使用详解
Jul 04 Python
用Python计算三角函数之acos()方法的使用
May 15 Python
Python中处理字符串之isalpha()方法的使用
May 18 Python
python清除指定目录内所有文件中script的方法
Jun 30 Python
python实现堆和索引堆的代码示例
Mar 19 Python
python2.7实现FTP文件下载功能
Apr 15 Python
Python 找到列表中满足某些条件的元素方法
Jun 26 Python
Python2和Python3中urllib库中urlencode的使用注意事项
Nov 26 Python
详解python的argpare和click模块小结
Mar 31 Python
python中有函数重载吗
May 28 Python
用python-webdriver实现自动填表的示例代码
Jan 13 Python
python re模块和正则表达式
Mar 24 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
实用函数2
2007/11/08 PHP
PHP写杨辉三角实例代码
2011/07/17 PHP
php中将字符串转为HTML的实体引用的一个类
2013/02/03 PHP
Thinkphp框架 表单自动验证登录注册 ajax自动验证登录注册
2016/12/27 PHP
修改yii2.0用户登录使用的user表为其它的表实现方法(推荐)
2017/08/01 PHP
PHP数据对象映射模式实例分析
2019/03/29 PHP
页面中js执行顺序
2009/11/09 Javascript
checkbox全选/取消全选以及checkbox遍历jQuery实现代码
2009/12/02 Javascript
JavaScript高级程序设计(第3版)学习笔记4 js运算符和操作符
2012/10/11 Javascript
解决jQuery动态获取手机屏幕高和宽的问题
2014/05/07 Javascript
用window.onerror捕获并上报Js错误的方法
2016/01/27 Javascript
js获取页面引用的css样式表中的属性值方法(推荐)
2016/08/19 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
2016/10/10 Javascript
AngularJS实现根据变量改变动态加载模板的方法
2016/11/04 Javascript
浅谈ES6新增的数组方法和对象
2017/08/08 Javascript
史上最全JavaScript数组去重的十种方法(推荐)
2017/08/17 Javascript
用React-Native+Mobx做一个迷你水果商城APP(附源码)
2017/12/25 Javascript
js+css实现打字效果
2020/06/24 Javascript
在layui中layer弹出层点击事件无效的解决方法
2019/09/05 Javascript
python通过urllib2获取带有中文参数url内容的方法
2015/03/13 Python
Python使用爬虫抓取美女图片并保存到本地的方法【测试可用】
2018/08/30 Python
python 含子图的gif生成时内存溢出的方法
2019/07/07 Python
Django框架ORM数据库操作实例详解
2019/11/07 Python
Python面向对象特殊属性及方法解析
2020/09/16 Python
python 中关于pycharm选择运行环境的问题
2020/10/31 Python
来自圣地亚哥的实惠太阳镜:Knockaround
2018/08/27 全球购物
在加拿大在线租赁和购买电子游戏:Game Access
2019/09/02 全球购物
Kiwi.com中国:找到特价机票并发现新目的地
2019/10/27 全球购物
实习单位接收函
2014/01/11 职场文书
时尚休闲吧创业计划书
2014/01/25 职场文书
2016春节慰问信范文
2015/03/25 职场文书
开业庆典嘉宾致辞
2015/08/01 职场文书
应收账款管理制度
2015/08/06 职场文书
关于实现中国梦的心得体会
2016/01/05 职场文书
CSS3 制作的图片滚动效果
2021/04/14 HTML / CSS
MYSQL(电话号码,身份证)数据脱敏的实现
2021/05/28 MySQL