深度学习大概分成两部分,模型训练和图像识别,模型训练涉及样本训练和样本验证,这个部分为深度学习的主要部分,通过调节样本集和训练参数控制结果精度。鉴于样本获取及计算机性能,这里使用现成的训练结果集,访问地址:https://github.com/isikdogan/deepwatermap。
1、安装环境
这里需要手动安装tensorflow,因为GUP版本计算速度比CPU版本快数十倍,因此安装GPU版本。GPU版本安装时,应注意对应的CUDA驱动。安装可参照:https://zhuanlan.zhihu.com/p/37086409。其他三个包为依赖包,必须安装。
2、识别影像准备
遥感影像进行深度学习,本文使用的模型涉及以下几个波段,需将下载的原始影像进行多波段融合,涉及的波段如下:
B2: Blue
B3: Green
B4: Red
B5: Near Infrared (NIR)
B6: Shortwave Infrared 1 (SWIR1)
B7: Shortwave Infrared 2 (SWIR2)
这里使用代码实现波段融合,代码如下:
import numpy as np
from osgeo import gdal_array
from osgeo import gdal
"""存储文件的列表维度为:imgs*11,既每个影像的波段文件都存放在单个列表里"""
import os
def read_landsat8_bands(base_path):
"""保存landsat8不同波段的路径(共11个波段)
base_path: 存储了多张影像的文件夹
mid_path: 存储了不同波段的文件夹,对应着单张影像
final_path: 最后一层可以直接打开的单张波段文件
bands:包含了波段路径的列表
"""
# 用于存储不同波段路径,维度是影像数量*波段数(11)
bands = []
num_bands = 11
# 用于定位波段用的关键字列表
keys = []
for k in range(num_bands):
key = 'B{num}.TIF'.format(num = k + 1)
keys.append(key)
# 读取最外层文件
base_files = os.listdir(base_path)
for i in range(len(base_files)):
bands.append([])
# 读取中层文件
mid_path = base_path + '\\' + base_files[i]
mid_file = os.listdir(mid_path)
# 得到最内层的波段文件
for final_file in mid_file:
final_path = mid_path + '\\' + final_file
for j in range(num_bands):
if keys[j] in final_file:
bands[i].append(final_path)
# 原始列表排序是1,10,11,2,3,...
# 按照倒数第5个字符进行排序(XXXB1.TIF)
bands[i].sort(key=lambda arr: (arr[:-5], int(arr[-5])))
# 返回波段列表和影像数量
return bands
base_path = r'G:\洞庭湖\input'
bands = read_landsat8_bands(base_path)
print(bands[0][:11])
# 读取波段
B2 = bands[0][1]
B3 = bands[0][2]
B4 = bands[0][3]
B5 = bands[0][4]
B6 = bands[0][5]
B7 = bands[0][6]
B2_np = np.array(gdal_array.LoadFile(B2))
B3_np = np.array(gdal_array.LoadFile(B3))
B4_np = np.array(gdal_array.LoadFile(B4))
B5_np = np.array(gdal_array.LoadFile(B5))
B6_np = np.array(gdal_array.LoadFile(B6))
B7_np = np.array(gdal_array.LoadFile(B7))
# 转化成ndarray形式
#B1_np = np.array(B1_gdal)
B_merger = np.array([B2_np, B3_np, B4_np,B5_np, B6_np, B7_np])
# 获取tif遥感影像的数据与投影信息
dataset1 = gdal.Open(B2)
im_geotrans = dataset1.GetGeoTransform()
im_proj = dataset1.GetProjection()
im_data = dataset1.ReadAsArray()
im_width = dataset1.RasterXSize
im_height = dataset1.RasterYSize
#im_bands = B_merger.shape
im_bands =6
band1 = dataset1.GetRasterBand(1)
datatype = band1.DataType
# 生成tif遥感影像
driver = gdal.GetDriverByName('GTiff') # 数据类型必须有,因为要计算需要多大内存空间
dataset = driver.Create(base_path+'\merger.tif', im_width, im_height, im_bands, datatype)
dataset.SetProjection(im_proj) # 写入投影
dataset.SetGeoTransform(im_geotrans) # 写入仿射变换参数
if im_bands == 1:
dataset.GetRasterBand(1).WriteArray(B_merger) # 写入数组数据
else:
for i in range(im_bands):
dataset.GetRasterBand(i + 1).WriteArray(B_merger[i])
del dataset
合并后结果如下:
3、运行模型识别湖泊
需下载好源代码和模型包,运行使用python代码,官方样例如下:
$ python inference.py --checkpoint_path checkpoints/cp.135.ckpt --image_path sample_data/sentinel2_example.tif --save_path water_map.png
其中–checkpoint_path 为模型存放位置标识,使用时将checkpoints/cp.135.ckpt改为模型存放位置,–image_path 为输入影像位置标识,使用时将sample_data/sentinel2_example.tif改为输入影像位置,–save_path为输出影像位置标识,使用时将water_map.png改为输出影像位置。
模型运行时,输入影像如下:
识别的结果如下:
栅格转矢量后:
按照模型设计者的说法,识别准确度达百分之九十以上…
版权归原作者 新月清光 所有, 如有侵权,请联系我们删除。