利用Python裁切tiff图像且读取tiff,shp文件的实例
我就废话不多说了,还是直接看代码吧!
fromosgeoimportgdal,gdalnumeric,ogr fromPILimportImage,ImageDraw fromosgeoimportgdal_array importos importoperator fromfunctoolsimportreduce gdal.UseExceptions() defreadTif(fileName): dataset=gdal.Open(fileName) ifdataset==None: print(fileName+"文件无法打开") return im_width=dataset.RasterXSize#栅格矩阵的列数 im_height=dataset.RasterYSize#栅格矩阵的行数 im_bands=dataset.RasterCount#波段数 band1=dataset.GetRasterBand(1) print(band1) print('BandType=',gdal.GetDataTypeName(band1.DataType)) im_data=dataset.ReadAsArray(0,0,im_width,im_height)#获取数据 im_geotrans=dataset.GetGeoTransform()#获取仿射矩阵信息 im_proj=dataset.GetProjection()#获取投影信息 im_blueBand=im_data[0,0:im_height,0:im_width]#获取蓝波段 im_greenBand=im_data[1,0:im_height,0:im_width]#获取绿波段 im_redBand=im_data[2,0:im_height,0:im_width]#获取红波段 im_nirBand=im_data[3,0:im_height,0:im_width]#获取近红外波段 return(im_width,im_height,im_bands,im_data,im_geotrans ,im_proj,im_blueBand,im_greenBand,im_redBand,im_nirBand) #保存tif文件函数 importgdal importnumpyasnp defwriteTiff(im_data,im_width,im_height,im_bands,im_geotrans,im_proj,path): if'int8'inim_data.dtype.name: datatype=gdal.GDT_Byte elif'int16'inim_data.dtype.name: datatype=gdal.GDT_UInt16 else: datatype=gdal.GDT_Float32 iflen(im_data.shape)==3: im_bands,im_height,im_width=im_data.shape eliflen(im_data.shape)==2: im_data=np.array([im_data]) else: im_bands,(im_height,im_width)=1,im_data.shape #创建文件 driver=gdal.GetDriverByName("GTiff") dataset=driver.Create(path,im_width,im_height,im_bands,datatype) if(dataset!=None): dataset.SetGeoTransform(im_geotrans)#写入仿射变换参数 dataset.SetProjection(im_proj)#写入投影 foriinrange(im_bands): dataset.GetRasterBand(i+1).WriteArray(im_data[i]) deldataset #Thisfunctionwillconverttherasterizedclippershapefile #toamaskforusewithinGDAL. defimageToArray(i): """ ConvertsaPythonImagingLibraryarraytoa gdalnumericimage. """ a=gdalnumeric.fromstring(i.tobytes(),'b') a.shape=i.im.size[1],i.im.size[0] returna defarrayToImage(a): """ Convertsagdalnumericarraytoa PythonImagingLibraryImage. """ i=Image.frombytes('L',(a.shape[1],a.shape[0]), (a.astype('b')).tobytes()) returni defworld2Pixel(geoMatrix,x,y): """ Usesagdalgeomatrix(gdal.GetGeoTransform())tocalculate thepixellocationofageospatialcoordinate """ ulX=geoMatrix[0] ulY=geoMatrix[3] xDist=geoMatrix[1] pixel=int((x-ulX)/xDist) line=int((ulY-y)/xDist) return(pixel,line) # #EDIT:thisisbasicallyanoverloaded #versionofthegdal_array.OpenArraypassinginxoff,yoffexplicitly #sowecanpasstheseparamsofftoCopyDatasetInfo # defOpenArray(array,prototype_ds=None,xoff=0,yoff=0): ds=gdal_array.OpenArray(array) ifdsisnotNoneandprototype_dsisnotNone: iftype(prototype_ds).__name__=='str': prototype_ds=gdal.Open(prototype_ds) ifprototype_dsisnotNone: gdalnumeric.CopyDatasetInfo(prototype_ds,ds,xoff=xoff,yoff=yoff) returnds defhistogram(a,bins=range(0,256)): """ Histogramfunctionformulti-dimensionalarray. a=array bins=rangeofnumberstomatch """ fa=a.flat n=gdalnumeric.searchsorted(gdalnumeric.sort(fa),bins) n=gdalnumeric.concatenate([n,[len(fa)]]) hist=n[1:]-n[:-1] returnhist defstretch(a): """ Performsahistogramstretchonagdalnumericarrayimage. """ hist=histogram(a) im=arrayToImage(a) lut=[] forbinrange(0,len(hist),256): #stepsize step=reduce(operator.add,hist[b:b+256])/255 #createequalizationlookuptable n=0 foriinrange(256): lut.append(n/step) n=n+hist[i+b] im=im.point(lut) returnimageToArray(im) defmain(shapefile_path,raster_path): #Loadthesourcedataasagdalnumericarray srcArray=gdalnumeric.LoadFile(raster_path) #Alsoloadasagdalimagetogetgeotransform #(worldfile)info srcImage=gdal.Open(raster_path) geoTrans=srcImage.GetGeoTransform() #CreateanOGRlayerfromaboundaryshapefile shapef=ogr.Open(shapefile_path) lyr=shapef.GetLayer(os.path.split(os.path.splitext(shapefile_path)[0])[1]) poly=lyr.GetNextFeature() #Convertthelayerextenttoimagepixelcoordinates minX,maxX,minY,maxY=lyr.GetExtent() ulX,ulY=world2Pixel(geoTrans,minX,maxY) lrX,lrY=world2Pixel(geoTrans,maxX,minY) #Calculatethepixelsizeofthenewimage pxWidth=int(lrX-ulX) pxHeight=int(lrY-ulY) clip=srcArray[:,ulY:lrY,ulX:lrX] # #EDIT:createpixeloffsettopasstonewimageProjectioninfo # xoffset=ulX yoffset=ulY print("Xoffset,Yoffset=(%f,%f)"%(xoffset,yoffset)) #Createanewgeomatrixfortheimage geoTrans=list(geoTrans) geoTrans[0]=minX geoTrans[3]=maxY #Mappointstopixelsfordrawingthe #boundaryonablank8-bit, #blackandwhite,maskimage. points=[] pixels=[] geom=poly.GetGeometryRef() pts=geom.GetGeometryRef(0) forpinrange(pts.GetPointCount()): points.append((pts.GetX(p),pts.GetY(p))) forpinpoints: pixels.append(world2Pixel(geoTrans,p[0],p[1])) rasterPoly=Image.new("L",(pxWidth,pxHeight),1) rasterize=ImageDraw.Draw(rasterPoly) rasterize.polygon(pixels,0) mask=imageToArray(rasterPoly) #Cliptheimageusingthemask clip=gdalnumeric.choose(mask,\ (clip,0)).astype(gdalnumeric.uint8) #Thisimagehas3bandssowestretcheachonetomakethem #visuallybrighter foriinrange(4): clip[i,:,:]=stretch(clip[i,:,:]) #Savenewtiff # #EDIT:insteadofSaveArray,let'sbreakallthe #SaveArraystepsoutmoreexplicityso #wecanoverwritetheoffsetofthedestination #raster # ###theoldwayusingSaveArray # #gdalnumeric.SaveArray(clip,"OUTPUT.tif",format="GTiff",prototype=raster_path) # ### # gtiffDriver=gdal.GetDriverByName('GTiff') ifgtiffDriverisNone: raiseValueError("Can'tfindGeoTiffDriver") gtiffDriver.CreateCopy("beijing1.tif", OpenArray(clip,prototype_ds=raster_path,xoff=xoffset,yoff=yoffset) ) print(raster_path) #Saveasan8-bitjpegforaneasy,quickpreview clip=clip.astype(gdalnumeric.uint8) gdalnumeric.SaveArray(clip,"beijing1.jpg",format="JPEG") gdal.ErrorReset() if__name__=='__main__': #shapefile_path,raster_path shapefile_path=r'C:\Users\Administrator\Desktop\裁切shp\New_Shapefile.shp' raster_path=r'C:\Users\Administrator\Desktop\2230542.tiff' main(shapefile_path,raster_path)
补充知识:python代码裁剪tiff影像图和转换成png格式+裁剪Png图片
先来看一下需要转换的tiff原始图的信息,如下图所示。
tiff转换成png和裁剪tiff的代码(opencv)
importcv2ascv importos """ 转换tiff格式为png+横向裁剪tiff遥感影像图 """ defConvert_To_Png_AndCut(dir): files=os.listdir(dir) ResultPath1="./RS_ToPngDir/"#定义转换格式后的保存路径 ResultPath2="./RS_Cut_Result/"#定义裁剪后的保存路径 ResultPath3="./RS_Cut_Result/"#定义裁剪后的保存路径 forfileinfiles:#这里可以去掉for循环 a,b=os.path.splitext(file)#拆分影像图的文件名称 this_dir=os.path.join(dir+file)#构建保存路径+文件名 img=cv.imread(this_dir,1)#读取tif影像 #第二个参数是通道数和位深的参数, #IMREAD_UNCHANGED=-1#不进行转化,比如保存为了16位的图片,读取出来仍然为16位。 #IMREAD_GRAYSCALE=0#进行转化为灰度图,比如保存为了16位的图片,读取出来为8位,类型为CV_8UC1。 #IMREAD_COLOR=1#进行转化为RGB三通道图像,图像深度转为8位 #IMREAD_ANYDEPTH=2#保持图像深度不变,进行转化为灰度图。 #IMREAD_ANYCOLOR=4#若图像通道数小于等于3,则保持原通道数不变;若通道数大于3则只取取前三个通道。图像深度转为8位 cv.imwrite(ResultPath1+a+"_"+".png",img)#保存为png格式 #下面开始裁剪-不需要裁剪tiff格式的可以直接注释掉 hight=img.shape[0]#opencv写法,获取宽和高 width=img.shape[1] #定义裁剪尺寸 w=480#宽度 h=360#高度 _id=1#裁剪结果保存文件名:0-N升序方式 i=0 while(i+h<=hight):#控制高度,图像多余固定尺寸总和部分不要了 j=0 while(j+w<=width):#控制宽度,图像多余固定尺寸总和部分不要了 cropped=img[i:i+h,j:j+w]#裁剪坐标为[y0:y1,x0:x1] cv.imwrite(ResultPath2+a+"_"+str(_id)+b,cropped) _id+=1 j+=w i=i+h """ 横向裁剪PNG图 """ deftoCutPng(dir): files=os.listdir(dir) ResultPath="./RS_CutPng_Result/"#定义裁剪后的保存路径 forfileinfiles: a,b=os.path.splitext(file)#拆分影像图的文件名称 this_dir=os.path.join(dir+file) img=Image.open(this_dir)#按顺序打开某图片 width,hight=img.size w=480#宽度 h=360#高度 _id=1#裁剪结果保存文件名:0-N升序方式 y=0 while(y+h<=hight):#控制高度,图像多余固定尺寸总和部分不要了 x=0 while(x+w<=width):#控制宽度,图像多余固定尺寸总和部分不要了 new_img=img.crop((x,y,x+w,y+h)) new_img.save(ResultPath+a+"_"+str(_id)+b) _id+=1 x+=w y=y+h if__name__=='__main__': _path=r"./RS_TiffDir/"#遥感tiff影像所在路径 #裁剪影像图 Convert_To_Png_AndCut(_path)
将转换成png后的图加载到软件中(专业软件ENVI5.3)查看结果详细信息如下图所示,成功的转换成png格式了。
下面是加载裁剪后的影像图(Tiff格式的)
deftoCutPng(dir):函数效果图如下图所示。
以上这篇利用Python裁切tiff图像且读取tiff,shp文件的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。