tif_clip.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import os
  2. from osgeo import gdal
  3. import numpy as np
  4. # os.environ['USE_PATH_FOR_GDAL_PYTHON'] = 'YES'
  5. # os.environ['PROJ_LIB'] = r'D:\app\anaconda\envs\py38\Library\share\proj'
  6. # 读取tif数据集
  7. def readTif(fileName):
  8. dataset = gdal.Open(fileName)
  9. if dataset == None:
  10. print(fileName + "文件无法打开")
  11. return dataset
  12. # 保存tif文件函数
  13. def writeTiff(im_data, im_geotrans, im_proj, path):
  14. if 'int8' in im_data.dtype.name:
  15. datatype = gdal.GDT_Byte
  16. elif 'int16' in im_data.dtype.name:
  17. datatype = gdal.GDT_UInt16
  18. else:
  19. datatype = gdal.GDT_Float32
  20. if len(im_data.shape) == 3:
  21. im_bands, im_height, im_width = im_data.shape
  22. elif len(im_data.shape) == 2:
  23. im_data = np.array([im_data])
  24. im_bands, im_height, im_width = im_data.shape
  25. # 创建文件
  26. driver = gdal.GetDriverByName("GTiff")
  27. dataset = driver.Create(path, int(im_width), int(im_height), int(im_bands), datatype)
  28. if(dataset!= None):
  29. dataset.SetGeoTransform(im_geotrans) # 写入仿射变换参数
  30. dataset.SetProjection(im_proj) # 写入投影
  31. for i in range(im_bands):
  32. dataset.GetRasterBand(i + 1).WriteArray(im_data[i])
  33. del dataset
  34. # 像素坐标和地理坐标仿射变换
  35. def CoordTransf(Xpixel, Ypixel, GeoTransform):
  36. XGeo = GeoTransform[0]+GeoTransform[1]*Xpixel+Ypixel*GeoTransform[2];
  37. YGeo = GeoTransform[3]+GeoTransform[4]*Xpixel+Ypixel*GeoTransform[5];
  38. return XGeo, YGeo
  39. '''
  40. 滑动窗口裁剪函数
  41. TifPath 影像路径
  42. SavePath 裁剪后保存目录
  43. CropSize 裁剪尺寸
  44. RepetitionRate 重复率
  45. '''
  46. def TifCrop(TifPath, SavePath, CropSize, RepetitionRate):
  47. if not os.path.exists(SavePath): os.makedirs(SavePath)
  48. dataset_img = readTif(TifPath)
  49. width = dataset_img.RasterXSize
  50. height = dataset_img.RasterYSize
  51. proj = dataset_img.GetProjection()
  52. geotrans = dataset_img.GetGeoTransform()
  53. img = dataset_img.ReadAsArray(0, 0, width, height)# 获取数据
  54. # 获取当前文件夹的文件个数len,并以len+1命名即将裁剪得到的图像
  55. new_name = len(os.listdir(SavePath)) + 1
  56. # 裁剪图片,重复率为RepetitionRate
  57. for i in range(int((height - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):
  58. for j in range(int((width - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):
  59. # 如果图像是单波段
  60. if(len(img.shape) == 2):
  61. cropped = img[int(i * CropSize * (1 - RepetitionRate)) : int(i * CropSize * (1 - RepetitionRate)) + CropSize,
  62. int(j * CropSize * (1 - RepetitionRate)) : int(j * CropSize * (1 - RepetitionRate)) + CropSize]
  63. # 如果图像是多波段
  64. else:
  65. cropped = img[:,
  66. int(i * CropSize * (1 - RepetitionRate)) : int(i * CropSize * (1 - RepetitionRate)) + CropSize,
  67. int(j * CropSize * (1 - RepetitionRate)) : int(j * CropSize * (1 - RepetitionRate)) + CropSize]
  68. XGeo, YGeo = CoordTransf(int(j * CropSize * (1 - RepetitionRate)),
  69. int(i * CropSize * (1 - RepetitionRate)),
  70. geotrans)
  71. crop_geotrans = (XGeo, geotrans[1], geotrans[2], YGeo, geotrans[4], geotrans[5])
  72. # 写图像
  73. writeTiff(cropped, crop_geotrans, proj, SavePath + "/%d.tif"%new_name)
  74. # 文件名 + 1
  75. new_name = new_name + 1
  76. # 向前裁剪最后一列
  77. for i in range(int((height-CropSize*RepetitionRate)/(CropSize*(1-RepetitionRate)))):
  78. if(len(img.shape) == 2):
  79. cropped = img[int(i * CropSize * (1 - RepetitionRate)) : int(i * CropSize * (1 - RepetitionRate)) + CropSize,
  80. (width - CropSize) : width]
  81. else:
  82. cropped = img[:,
  83. int(i * CropSize * (1 - RepetitionRate)) : int(i * CropSize * (1 - RepetitionRate)) + CropSize,
  84. (width - CropSize) : width]
  85. XGeo, YGeo = CoordTransf(width - CropSize,
  86. int(i * CropSize * (1 - RepetitionRate)),
  87. geotrans)
  88. crop_geotrans = (XGeo, geotrans[1], geotrans[2], YGeo, geotrans[4], geotrans[5])
  89. # 写图像
  90. writeTiff(cropped, crop_geotrans, proj, SavePath + "/%d.tif"%new_name)
  91. new_name = new_name + 1
  92. # 向前裁剪最后一行
  93. for j in range(int((width - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):
  94. if(len(img.shape) == 2):
  95. cropped = img[(height - CropSize) : height,
  96. int(j * CropSize * (1 - RepetitionRate)) : int(j * CropSize * (1 - RepetitionRate)) + CropSize]
  97. else:
  98. cropped = img[:,
  99. (height - CropSize) : height,
  100. int(j * CropSize * (1 - RepetitionRate)) : int(j * CropSize * (1 - RepetitionRate)) + CropSize]
  101. XGeo, YGeo = CoordTransf(int(j * CropSize * (1 - RepetitionRate)),
  102. height - CropSize,
  103. geotrans)
  104. crop_geotrans = (XGeo, geotrans[1], geotrans[2], YGeo, geotrans[4], geotrans[5])
  105. writeTiff(cropped, crop_geotrans, proj, SavePath + "/%d.tif"%new_name)
  106. # 文件名 + 1
  107. new_name = new_name + 1
  108. # 裁剪右下角
  109. if(len(img.shape) == 2):
  110. cropped = img[(height - CropSize) : height,
  111. (width - CropSize) : width]
  112. else:
  113. cropped = img[:,
  114. (height - CropSize) : height,
  115. (width - CropSize) : width]
  116. XGeo, YGeo = CoordTransf(width - CropSize,
  117. height - CropSize,
  118. geotrans)
  119. crop_geotrans = (XGeo, geotrans[1], geotrans[2], YGeo, geotrans[4], geotrans[5])
  120. writeTiff(cropped, crop_geotrans, proj, SavePath + "/%d.tif"%new_name)
  121. new_name = new_name + 1
  122. # 将影像1裁剪为重复率为0.1的 64*64的数据集
  123. TifCrop("data/tif/1.tif","data/tif_crop",256, 0.25)