
简介这是一份基于Python深度学习的高分辨率城市遥感图像水体提取系统源码项目源自评审分98.5分的大四毕业设计适合计算机、人工智能、数据科学、通信等相关专业学生用于毕业设计、课程设计或期末大作业。项目针对城市高分影像中水体区域的自动化识别与分割问题完整覆盖数据预处理、U-Net与Attention U-Net网络构建、训练求解与测试评估等流程代码模块划分清晰初学者可按脚本逐步掌握语义分割项目的常见套路有基础者也可直接基于现有结构做二次开发。整个资源共56个文件压缩包仅1.42MB。核心为22个py脚本涵盖主流程、网络结构定义、数据集加载、模型训练与评估、单图测试等功能模块另有2个pth训练权重文件、2个csv评估结果、26张png网络结构图与分割效果图以及md/txt说明文档目录结构紧凑便于快速定位所需代码。源码上传前已经本地运行成功且功能测试无误目前已有196人学习下载作为毕设参考或深度学习实战练习具有较高学习价值。1. 城市遥感水体提取为什么这个毕设源码值得你跑一遍遥感图像水体提取在环保监测、城市规划和灾害评估里是非常基础的需求但高分辨率城市影像的挑战在于建筑物阴影、道路反光、植被遮挡这些干扰因素传统阈值分割和光谱指数方法很难把这些和水体干净地分开。基于python深度学习的方案可以直接学习水体的空间分布特征泛化能力比传统方法强很多。这个项目是一个完整可运行的毕业设计源码网络部分包含U-Net和Attention U-Net数据预处理、训练、验证和测试流程都封装好了适合做毕设和课程设计的计算机相关专业学生也适合想了解遥感语义分割完整流程的从业者。我拿到源码后实际跑通了一遍整个流程对新手比较友好把数据准备好就能开始训练和测试。2. 网络选型与代码结构U-Net和Attention U-Net的选择逻辑2.1 两个网络模型的核心差异network.py文件里实现了两个经典语义分割网络一个是标准U-Net另一个是带注意力机制的Attention U-Net。U-Net是编码-解码结构编码器逐步缩小特征图尺寸同时增加通道数解码器逐步恢复分辨率跳跃连接把浅层细节特征传给深层让输出结果保留边缘信息。在高分辨率遥感图像里建筑物阴影和水体边界常常连在一起U-Net能通过跳跃连接保住局部细节这是它能胜任城市遥感水体提取的基础。Attention U-Net在跳跃连接上加了注意力门控能学习哪些特征更重要。默认的注意力模块会计算一个门控系数对编码器特征进行加权保留水体相关区域的特征抑制阴影和道路的反响特征。在内存受限情况下Attention U-Net比普通U-Net稍微重一点但分割精度通常会更好水体边缘会更加连续。network.py中的U-Net代码核心部分如下class ConvBlock(nn.Module): def __init__(self, in_channels, out_channels): super().__init__() self.double_conv nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue), nn.Conv2d(out_channels, out_channels, kernel_size3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue), ) def forward(self, x): return self.double_conv(x)这里使用两次3x3卷积加BatchNorm加ReLU组合是U-Net的基本卷积块。padding设为1保持特征图尺寸不变BatchNorm能加快收敛并减少不同批次数据的分布差异。读代码时如果发现BatchNorm和ReLU的位置有不同版本输出的性能会有细微差异我一般习惯保持源码默认设置不做无谓改动。2.2 从dataset.py到data_loader.py数据管线的组装方式dataset.py和data_loader.py是数据管线的关键部分。dataset.py主要是定义了Dataset类用于读取原始遥感影像和对应的标注掩码。遥感图像一般是RGB三波段的高分辨率tif或jpg图片标注图是单通道的png二值图水体像素为255背景为0。data_loader.py则通过DataLoader把这些样本包成多个批次并支持随机打乱、多线程预加载和归一化。dataset.py中一个可以学习的核心预处理逻辑# 数据增广策略只做几何变换不做颜色扭曲 if self.transform: img Image.fromarray(img) mask Image.fromarray(mask) if random.random() 0.5: img img.transpose(Image.FLIP_LEFT_RIGHT) mask mask.transpose(Image.FLIP_LEFT_RIGHT) # 其他随机裁剪、旋转操作类似这里的关键是没有对图像做颜色抖动因为遥感水体提取任务中颜色和光谱特征极其重要颜色增强会误导模型学错误特征。训练时可用随机翻转、随机旋转、随机裁剪让模型适应不同方向的纹理特征但不要动颜色通道。显存不足时常见做法是在Dataset里直接输出原始尺寸在batch层面做小尺寸随机裁剪这比缩放到固定尺寸的效果要好。3. 数据准备标注格式与预处理脚本的实际用法3.1 数据集目录组织与训练样本格式压缩包里的data_set目录划分了train、valid、test三个子集每个子集下面有image和annotation两个目录。train下面放的是用于训练的高分辨率城市遥感图像和对应的分割掩码valid用于训练中验证模型泛化能力test用于最终效果测试。Urben_pre目录存放经过预处理的增强图片和掩码可以直接作为补充训练数据。要跑通这个项目数据目录必须和代码里data_loader.py预设的相对路径保持一致否则第一次启动大概率会报文件不存在。我处理这类项目的一般习惯是先把一个训练样本的图像和标注图可视化看一下确认前景背景分配合理再开始训练。3.2 enhance_image.py和data_preprocess.py的主要功能enhance_image.py实现了简单的图像增强例如对比度拉伸和锐化这能改善薄雾覆盖的城市影像质量。data_preprocess.py实现了把原始大图裁剪成训练用小块的过程因为高分辨率遥感图通常很大直接输入显卡容易显存溢出。这个脚本常见做法是在原图上滑动窗口裁剪同时同步裁剪对应的标注掩码并检查裁剪区域是否包含足够比例的水体像素如果目标过少则丢弃避免过多无效训练样本。data_preprocess.py中的关键逻辑如下# 滑动窗口裁剪原图和标注图保持两者对齐 for y in range(0, height - crop_size 1, stride): for x in range(0, width - crop_size 1, stride): img_crop img[y:ycrop_size, x:xcrop_size] lbl_crop label[y:ycrop_size, x:xcrop_size] # 筛选如果该块水体像素占比低于阈值跳过 if np.sum(lbl_crop 0) / (crop_size * crop_size) ratio_th: continue np.save(...)这个脚本的可改参数包括crop_size裁剪尺寸、stride滑动步长和ratio_th最低正样本占比。crop_size一般取256或512stride小于crop_size时会产生重叠区域增加样本量但也会引入重复数据所以要控制重叠比例。ratio_th设太低会塞进大量背景块设太高容易丢弃许多有用的复杂场景样本我实测0.05到0.1是比较合理的区间。附带的说明.txt会告诉你虚拟环境需要的依赖版本例如pytorch、torchvision、numpy、pillow等。如果本地显卡显存有限建议在训练配置中关闭数据增强里的大尺寸随机裁剪或者把输入尺寸改成256待验证通过后再换回512来提升精度。4. 训练与验证从main.py到evaluation.py的完整流程4.1 main.py和solver.py的工作流main.py是程序入口负责读取配置、创建数据集和实例化solver。打开main.py可以看到它加载了train和valid路径然后创建solver对象并调用training方法。整个训练过程的细节都封装在solver.py中优化器一般选择Adam初始学习率通常在1e-4左右并配合StepLR或CosineAnnealingLR学习率衰减。以下是一个比较典型的Adam配合StepLR的实现逻辑# solver.py 中的优化器构造部分 optimizer torch.optim.Adam(model.parameters(), lrinit_lr, weight_decay1e-4) scheduler torch.optim.lr_scheduler.StepLR(optimizer, step_sizeepochs // 3, gamma0.5)weight_decay设为1e-4有助于抑制过拟合StepLR每过epochs/3轮迭代把学习率减半让训练后期更稳。第一次跑时可以把epochs设置小一些比如20验证整体流程能跑通再加量。4.2 模型评估从测试脚本到精度指标test目录中的test_one_data.py用于对单张图片进行推理会加载训练好的train.pth权重文件输出预测的掩码。evaluation.py负责计算训练结果在验证集或测试集上的指标核心指标一般是IoU交并比和F1-Score而像素精度反而是次要的。因为在水体提取任务里类别不平衡非常严重背景像素可能占90%以上即使全预测成背景像素精度也可能很高所以主要关注IoU。evaluation.py中典型的指标计算代码# 计算IoUintersection / union intersection np.logical_and(pred_mask, true_mask).sum() union np.logical_or(pred_mask, true_mask).sum() iou intersection / (union 1e-6)输出结果会写入result目录下的res.csv记录每个epoch或每个测试样本的IoU、F1、像素精度等数值方便训练中比较模型变化。我实际操作时会每个epoch末尾记录一次验证集的IoU并把表现最好的模型另存为best_model.pth这样即使训练后半段出现过拟合也依然有可用权重。如果自己测试数据最好先用test_one_data.py跑两三张图肉眼对比预测遮罩和标注图的差别。如果预测结果中有大量细小碎块通常是后处理去噪不够可以通过形态学开闭运算清理小于特定像素数的连通域。5. 避坑指南复现这个项目时最容易踩的5个坑5.1 坑一路径配置不对DataLoader直接报文件不存在现象运行main.py后立即提示FileNotFoundError路径拼写错误或者把数据文件夹放在别的目录下。原因data_loader.py里默认按项目相对路径找图像和标注比如data_set/train/image这种结构。如果你把数据集单独放到桌面或者自己重命名了文件夹代码就找不到了。解决先把压缩包解压后保持一级目录结构不变再打开data_loader.py检查里面的绝对路径变量改成自己机器上真实数据所在的位置。以后每次换机器运行项目第一件事就是检查这堆路径变量。5.2 坑二显存不足导致训练OOM中断现象一张NVIDIA 1060 6G显卡batch_size设8训练刚开始就报CUDA out of memory训练中断。原因默认batch_size可能是按更高配置显卡设定的而且训练尺寸为512或更大显存不够用。解决把batch_size调成2或4同时把输入图像尺寸改到256。一般做法是在solver.py里找到batch_size变量再找到transform中的尺寸设置。这样训练能跑通模型的精度也会略有下降但至少流程完整换到更好显卡或调大batch_size后再提升精度。5.3 坑三train.pth与其他代码版本不匹配现象直接拿train.pth去predict.py或其他测试脚本跑结果网络层名称对应不上加载权重时报错。原因压缩包里的train.pth是配合项目内main.py和network.py训练出来的权重名称与配置文件是严格绑定的。你自己改了模型结构或换了版本后再加载这个权重就不匹配。解决第一次运行时不要乱改network.py的结构。如果只是测试功能直接用原始代码加载train.pth即可。需要二次开发时先基于原模型预训练权重进行微调训练或用pytorch的load_state_dict(..., strictFalse)来忽略不匹配层。5.4 坑四训练集和验证集划分不当导致准确率虚高或偏低现象验证集和训练集来自同一张遥感大图的相邻裁剪区域验证时看起来高达95%以上但一放到新城市图上效果一般水体边缘失真。原因高分辨率遥感影像中相邻裁剪块的相关性很强如果预处理脚本滑窗裁完随机分到训练集和验证集等同于“背答案”模型并没有真正泛化到新场景。解决正确做法是先按地理位置或图像文件划分而不是按裁剪块划分。把一张完整大图的一部分区域用于训练另一部分完全不参与训练的区域放在验证集中这样才能检验模型的学习能力。5.5 坑五结果图水体边缘锯齿感强烈碎块多现象模型提取出的水体分布整体正确但边缘凹凸不平大量零散小色块被识别成水体。原因模型对每个像素独立预测没有考虑上下文一致性尤其是高分影像中道路表面的反光也容易造成小块误检。解决在预测环节加一个后处理步骤用opencv做中值滤波或形态学开运算去掉小块噪点再用闭运算填补空隙。这类后处理一般能让IoU提升0.5到1个百分点效果立竿见影。6. 进阶用法修改训练配置、批量推理与结果可视化验证完整个流程后可以把这套基础版本往自己的实际需求上改。最值得改的三个方向是调整模型输入大小、修改类别数量和增加模型集成。项目本身是二分类任务如果你想把任务改成水体、道路、植被、建筑四类地物提取需要把标注图改成多通道one-hot编码对应修改dataset.py和evaluation.py里的类别数量同时把网络输出通道数从2改成4再重新训练。批量推理时常见做法是写一个循环脚本扫描整个测试集文件夹逐张图读取、预处理、推理、保存结果同时把所有预测值汇总到一张大图上进行可视化对比。我可以给出一个典型批量推理的伪代码结构# 批量测试脚本循环遍历test图片 for img_path in test_img_list: img read_and_normalize(img_path) with torch.no_grad(): pred model(img.unsqueeze(0).cuda()) pred_mask pred.argmax(dim1).squeeze().cpu().numpy() cv2.imwrite(os.path.join(save_dir, img_path.name), pred_mask * 255)其中argmax取通道维度上最大值对应的类别得到二值掩码再映射到0和255的像素值保存。注意保存前一定要确认原始影像和掩码的投影坐标系、地理位置是严格对齐的否则后面叠加分析会错位。另一个可以提升精度的手段是TTA测试时增强把测试图做水平翻转、垂直翻转分别预测后取平均。TTA在遥感分割上效果稳定耗时会增加3到4倍但能明显改善边界连续性我一般在验收前跑一次。结果可视化时推荐把原图、预测掩码、真实标注三者拼接成对比图便于检查细节差异。如果发现某类场景反复出现误检就针对这类场景补充样本或调整loss权重。从那以后我每次部署模型前都会强制走一遍“检查路径 → 观察数据 → 小批量训练 → 验证集评估 → 测试集后处理”这个流程实际能减少大量低级错误。希望这份拆解能帮你在自己的毕设或实际项目中少走弯路。本文还有配套的精品资源点击获取