pythonmapdel_地质男转行学遥感Python——遥感数据裁剪的具体实现
前几天在DMSP数据预处理中介绍了利用gdal.warp()来实现影像裁剪,今天介绍如何通过代码一步步实现影像裁剪功能。影像裁剪的过程其实就是读取影像数据,获取影像数据的仿射、投影信息,将地理坐标转换成像素坐标,读取用于裁剪的矢量数据,获取相应的投影信息,将矢量数据范围坐标转换成像素坐标,生成用于裁剪的掩膜文件(0,1),根据掩膜文件,生成掩膜范围内实际裁剪array(可以理解为矩阵点乘,掩膜文件为1的保留有影像数据值,为0的则影像数据值变为0),最后对数据进行写入,生成裁剪后的影像文件。
结合实际操作,逐步说明吧。
首先第一步影像数据、栅格数据的读入,及相关信息的生成(主要就是放射信息,地理坐标转换为像素坐标)。先是影像数据读入。
#定义基础数据打开及基础信息获取函数
def Get_Imgdata(filepath):
ds = gdal.Open(filepath)
#img_band = ds.GetRasterBand(1)
#band_arr = img_band.ReadAsArray()
#bandnum = img_ds.RasterCounter
#img_width =img_band.XSize
#img_height = img_band.YSize
#img_bandnum = img_ds.RasterCount
geo = ds.GetGeoTransform()
prj = ds.GetProjection()
return ds,geo,prj
影像数据读入及相关基础信息获取还是比较容易的,接下来是矢量数据读入和坐标转换。
def Get_shpdata(filepath,img_geo):
ds = ogr.Open(filepath,0)
layer = ds.GetLayer()
shp_extent = layer.GetExtent()
#luxy = (shp_extent[0],shp_extent[3])
ulx,uly = shp_extent[0],shp_extent[3]
#rlxy = (shp_extent[1],shp_extent[2])
lrx,lry = shp_extent[1],shp_extent[2]
#实际坐标转换成像素坐标,获取像素裁剪范围
inv_img_geo = gdal.InvGeoTransform(img_geo)
ulxy_pixel = World2Pixel(inv_img_geo,ulx,uly)
lrxy_pixel = World2Pixel(inv_img_geo,lrx,lry)
#pxwidth = lrxy_pixel[0]-ulxy_pixel[0]
#pxheight = lrxy_pixel[1]-ulxy_pixel[1]
print(ulxy_pixel,lrxy_pixel)
feat = layer.GetFeature(0)
feat_geom = feat.GetGeometryRef()
points = feat_geom.GetGeometryRef(0)
points_list = []
points_pixel =[]
for p in range(points.GetPointCount()):
points_list.append((points.GetX(p),points.GetY(p)))
#转换成像素坐标
#在转之前需要修改仿射信息,不修改的话后面的mask文件会出错
img_geo0 = list(img_geo)
img_geo0[0] = ulx
img_geo0[3] = uly
inv_img_geo0 = gdal.InvGeoTransform(img_geo0)
for p in points_list:
points_pixel.append(World2Pixel(inv_img_geo0,p[0],p[1]))
return ulxy_pixel,lrxy_pixel,img_geo0,points_pixel
def World2Pixel(geotrans,x,y):
#inv_geotrans = gdal.InvGeoTransform(geotrans)
xy_pixel = gdal.ApplyGeoTransform(geotrans,x,y)
# 将转换后的结果进行取整,必须要做的
int_x_pixel,int_y_pixel = map(int,xy_pixel)
return (int_x_pixel,int_y_pixel)
这一部分内容就比较复杂一些,里面有一些小的技巧和一些容易出错的地方。第一个要说明的是我定义了一个地理坐标转换像素坐标的函数,在这里很多其他类似的操作,都是利用仿射信息进行计算(仿射信息内提供了数据的起始点,也就是左上角的坐标,根据pixelwidth,pixelheight进行计算),而我给大家提供更为方便的两个函数,gdal.InvGeoTransform和ApplyGeoTransform,可以轻松的实现地理坐标与像素坐标之间的转换。第二个要说明的是矢量拐点坐标的获取,对于规则形状的矢量范围来说,很容易,但是实际情况是,裁剪矢量范围一般是不规则的,比如一个地方的行政区划,这样的矢量数据通常含有众多拐点,因此获取每一个拐点坐标,并进行坐标转换,才能实现后面的裁剪工作。 feat = GetGeometryRef() 和points = feat_geom.GetGeometryRef(0)结合循环,就可以逐个提取矢量要素的拐点坐标了。第三个要说的是仿射信息的更改。因为是需要用矢量数据进行裁剪,后续的掩膜文件生成和文件的写入,的仿射信息的起始点坐标应该是矢量文件的左上角坐标,这是需要修改的,也是容易出错的地方。
再接下来就是掩膜文件的生成。生成一个范围与矢量数据一致的淹没文件,掩膜文件范围是矢量数据的四至范围,矢量数据范围内的掩膜数值为1,之外的为0,大家可以去自己生成试一下。
def imageToArray(i):
a=gdalnumeric.fromstring(i.tobytes(),'b')
a.shape=i.im.size[1], i.im.size[0]
return a
def Create_Mask(x,y,p):
clippoly = Image.new("L", (x,y), 1)
draw_ploy = ImageDraw.Draw(clippoly)
draw_ploy.polygon(p, 0)
mask = imageToArray(clippoly)
print(mask)
return mask
然后就是实现数据的裁剪。
def Clip(choose,ds,mask,new_geo,columns,rows,offset):
band = ds.GetRasterBand(1)
driver = gdal.GetDriverByName('GTiff')
out_ds = driver.Create(r'D:\gdal_data\CLIP\B4_Clip.tif',columns,rows,1,band.DataType)
out_ds.SetProjection(img_ds.GetProjection())
out_ds.SetGeoTransform(new_geo)
out_band = out_ds.GetRasterBand(1)
band_arr = band.ReadAsArray(offset[0],offset[1],columns,rows)
if choose == 'v':
clip_data = gdalnumeric.choose(mask, (band_arr,0))
if choose == 'c':
clip_data = band_arr
out_band.WriteArray(clip_data)
out_ds.FlushCache()
del out_ds
我这里写着玩的,'V'代表不规则矢量数据,'C'代表规则矢量数据。体验一下。最后就是调用前面所有操作的主函数了。
if __name__ == '__main__':
img_path = r'D:\gdal_data\CLIP\LC81270372014355LGN00_B4.tif'
shp_path = r'D:\gdal_data\CLIP\范围_proj.shp'
img_ds,img_geo,img_prj = Get_Imgdata(img_path)
UL_pixel,LR_pixel,img_geonew,pts_pixel = Get_shpdata(shp_path,img_geo)
cols = LR_pixel[0] - UL_pixel[0]
rows = LR_pixel[1] - UL_pixel[1]
clip_mask = Create_Mask(cols,rows,pts_pixel)
clip_choose = input()
if clip_choose == 'v':
print('Execute Vector Clip!!')
Clip(clip_choose,img_ds,clip_mask,img_geonew,cols,rows,UL_pixel)
if clip_choose == 'c':
print('Execute Regular_shape Clip!!')
Clip(clip_choose,img_ds,clip_mask,img_geonew,cols,rows,UL_pixel)
else:
print("please enter 'v' or 'c',otherwise there is no way to clip!" )
#print()
#Clip()
至此,就实现了数据的裁剪。照例贴上裁剪的案例吧。这里我只裁剪了单一波段,起始多波段裁剪过程一样,就是最后写入的时候变换一下数据写入的方式,前面介绍过了,就不再重复说了。
OK,今天就分享这些。之前说过要简单介绍一下GEE的python的一些基础,例如ee.Geometry,ee.Feature, ee.Image等,我想在介绍这个内容之前,还想简单介绍一下gdal矢量数据创建,就比如如何创建点、线、面等,之后再介绍GEE,这样能够有个比较好的对比。其实GEE的话,还是推荐大家用google自带的,本地python化的话,有个很大的问题就是效率的问题。我用GEE平台做一个省的土地利用分类工作,在基础数据准备好的基础上,用GEE自带的分类模型跑的话,非常的快,而我用python写代码跑的话,效率就低很多,可能还有改进的地方吧。
pythonmapdel_地质男转行学遥感Python——遥感数据裁剪的具体实现相关推荐
- 40多岁转行学了Python来得及吗?能谋生吗?
坐标深圳,一个亲戚,以前做点小生意,最近半年学起了Python,现在的水平大概是能爬虫抓点东西,能画些图表.家人想知道他是否能靠这个谋生,比如打打零工什么的.虽然我自己也是IT行业的,但真不知道他这样 ...
- 30岁转行学Python晚吗?在这个年龄我为什么会焦虑?
30岁转行学Python晚吗?在这个年龄我为什么会焦虑? (故事源自粉丝投稿) 不知道你是否有过这样的经历,就是在临近30岁的这几年,可能是28,可能是29,会突然有一天,你就不得不以一个顶梁柱的角色 ...
- python好学吗一般要学多久-转行学Python开发难吗,月薪过万需要多久
原标题:转行学Python开发难吗,月薪过万需要多久 我们知道,你最担心学习后能不能顺利就业,薪资能不能达到预期,付出和收获能否成正比.对于Python的招聘岗位和薪资我们曾经分析过很多.那么在达内学 ...
- 只会python好找工作吗-转行学Python能拿多少钱?二线工作好找吗?
今天我们要分享给大家的是转行学Python能拿多少钱,二线工作现状的问题,感兴趣就一起来看看吧: 在编程界,Python是一种神奇的存在.有人认为,只有用Python才能优雅写代码,提高代码效率;但另 ...
- python开发转行做数据分析_转行学IT,Java、Python、大数据选择学哪个发展好?
对薪资不满意.担心自己以后不好找工作,不少人都会选择参加培训,转行IT行业.当然很多想要转行IT的人,都会犹豫选择哪门编程语言学习比较好,Python.Java.大数据作为比较热门行业技术,不少人都很 ...
- 客座编辑:李国庆(1968-),男,博士,中国科学院遥感与数字地球研究所研究员、博士生导师...
李国庆(1968-),男,博士,中国科学院遥感与数字地球研究所研究员.博士生导师,卫星数据技术部主任,北京市科技新星计划入选者,世界数据系统(WDS)科学委员会委员.主要研究方向为高性能地学计算.空间 ...
- python零基础能学吗-Python编程语言好学吗?零基础转行能学Python吗?
Python编程语言好学吗?零基础转行能学Python吗?人工智能时代的来临催生了很多新兴行业,Python是最具代表性也是比较热门的技术之一.有人看好Python入门简单.功能强大的特性,选择转行从 ...
- 学python有前途吗-2019年转行学Python有还前途吗?如何学习Python?
2019年转行学Python有还前途吗?如何学习Python?下面和千锋广州小编一起来看看吧! Python是一种计算机程序设计语言.你可能已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流 ...
- Python遥感图像处理应用篇(二十二):Python+GDAL 批量等距离裁剪影像-续
之前写过一篇按照指定行列号数量来进行影像等距离裁剪的博客,链接如下: Python遥感图像处理应用篇(二十二):Python+GDAL 批量等距离裁剪影像_空中旋转篮球的博客-CSDN博客_pytho ...
- Python遥感图像处理应用篇(九):使用NDVI指数数据批量计算植被覆盖度FVC
1.植被覆盖度相关概念 植被覆盖度( Fractional Vegetation Cover,FVC)指植被(包括叶.茎.枝)在地面的垂直投影面积占统计区总面积的百分比.通常采用像元二分模型计算: 计 ...
最新文章
- 各大知名企业的Research展示
- SpringBoot + Mybatis + Druid + PageHelper 实现多数据源并分页
- C语言从0到1·源程序,源文件,目标文件之间的关系
- PAT甲级1092 To Buy or Not to Buy :[C++题解]哈希表
- 差分约束 【bzoj2330】[SCOI2011]糖果
- Guava入门~Charsets
- 首个单芯片超小封装I2C转PWM解决方案
- python是什么课程-Python课程包括哪些内容?
- HybridDB PostgreSQL Sort、Group、distinct 聚合、JOIN 不惧怕数据倾斜的黑科技和原理 - 多阶段聚合...
- FFT海水模拟(又来了-_-b)
- 初触Python,关于pyquery解析html(百度贴吧)
- kettle linux下的目录怎么看_Linux系统各目录下指令解析
- plsqldev1105_x64与instantclient_11_2配置使用
- windows linux jdk8 jdk11下载
- C++ Primer 中文版(第 5 版)练习解答合集
- SC16IS750在STM32的应用
- 个人六年的成长与工作经验分享
- Oracle drop table
- php代码运行后空白什么原因,PHP空白页面常见原因及解决方法
- 单日涨粉10w+,他做了什么让流量和口碑都火爆?