【pytorch代码+数据集】基于GAN的自然风景图像磨损修复项目-深度学习

在这里插入图片描述

目录

  • 项目简介

  • 环境配置

  • 数据集介绍

  • 项目结构

  • 核心实现流程

  • 详细使用步骤

    • 1. 下载数据集
    • 2. 生成"老化"图像
    • 3. 训练修复模型
    • 4. 修复单张图像
  • 各文件功能详解

  • 网络架构设计

  • 损失函数详解

  • 实验结果与分析

  • 常见问题解答

  • 总结与展望

  • 代码清单【附件】

项目简介

本项目实现了一个基于生成对抗网络(GAN)的老旧风景照片修复系统。通过对干净的风景照片施加噪声、色彩衰减和划痕等效果,模拟自然老化的照片,然后训练GAN网络学习从老化照片恢复到原始清晰照片的映射关系。这种技术可以应用于修复实际的老旧照片,恢复其原有的清晰度和色彩。

与传统的图像修复方法相比,基于GAN的方法能够更好地保留图像的细节和纹理信息,产生更加自然、真实的修复效果。本项目特别针对风景照片进行了优化,能够有效处理各种老化效应,如色彩褪色、噪点增加和表面划痕等。

该工程基于GAN(生成对抗网络)实现自然风景图片的修复。其核心流程为:

  1. 从原始清晰图像生成"磨损"图像(高斯噪声、色彩漂移、划痕等);
  2. 使用自定义Dataset加载成对图像;
  3. 定义U-Net风格多分支生成器与PatchGAN判别器;
  4. 训练GAN,优化对抗+内容+可选感知损失;
  5. 验证阶段评估PSNR/SSIM;
  6. 单图推理完成修复。

环境配置

本项目使用Python和PyTorch开发,主要依赖包括:

pip install torch torchvision tqdm opencv-python pillow scikit-image kagglehub

推荐使用conda创建虚拟环境:

conda create -n landscape-repair python=3.8
conda activate landscape-repair
pip install torch torchvision tqdm opencv-python pillow scikit-image kagglehub

GPU环境配置(推荐使用CUDA加速训练):

  • CUDA 11.3+
  • PyTorch 1.10+
  • 至少8GB显存的NVIDIA GPU(GTX 1080Ti或更高)
  • VRAM需求:batch_size=8,img_size=256时约需6GB显存

CPU训练也可行,但速度会大幅降低(约为GPU的1/10)。如需在CPU上训练,请调整batch_size为较小值(如2或4)。

数据集介绍

本项目使用Kaggle上的"Landscape Recognition Image Dataset",包含约12,000张高质量风景图像,分为以下主要类别:

  • Coast(海岸):约2000张图像,展示各种海岸线、沙滩和海洋场景
  • Desert(沙漠):约2000张图像,展示沙漠景观和荒漠地形
  • Forest(森林):约2000张图像,包含各种森林、树木和植被场景
  • Glacier(冰川):约2000张图像,展示冰川、雪山和冰雪景观
  • Mountain(山脉):约2000张图像,包含各种山脉和高地景观
  • Buildings(建筑):约2000张图像,展示与自然景观结合的建筑物

每个类别的图像都有训练集和测试集的划分。图像分辨率大多在1000×1000像素左右,格式为JPEG。该数据集具有丰富的纹理细节和色彩变化,适合用于训练和测试图像修复模型。

数据集总大小约为500MB,下载后需解压并组织为项目所需的目录结构。

项目结构

初始项目结构如下:

GAN_landscape_img_repair-master/
├── add_noise.py            # 图像老化处理脚本
├── dataset.py              # 数据集加载类
├── download_datasets.py    # 数据集下载脚本
├── inference.py            # 单图像推理脚本
├── model.py                # 模型架构定义
├── train.py                # 模型训练脚本
└── utils.py                # 工具函数

核心实现流程

本项目的核心实现流程分为六个主要步骤:

1. 从原始清晰图像生成"磨损"图像

  • 使用add_noise.py脚本对原始风景照片应用多种老化效果

  • 主要包括三种老化处理:

    • 色彩调整:降低饱和度、微调色相和亮度,模拟老照片的褪色效果
    • 高斯噪声:添加随机强度的噪点,模拟胶片颗粒感和时间侵蚀
    • 随机划痕:添加浅色线条,模拟照片表面的物理损伤

2. 使用自定义Dataset加载成对图像

  • dataset.py中的LandscapeDataset类负责加载和预处理图像对
  • 自动配对"原始-老化"图像,确保一一对应
  • 实现图像预处理:调整尺寸、标准化、可选的数据增强
  • 提供批量加载机制,支持PyTorch的DataLoader接口

3. 定义U-Net风格多分支生成器与PatchGAN判别器

  • model.py中实现两个网络架构:

    • RepairNetGenerator:多分支U-Net生成器,由共享编码器、三路解码器和细节增强模块组成
    • RepairNetDiscriminator:PatchGAN判别器,判断图像块级别的真假
  • 生成器专注于不同尺度的特征重建,判别器关注局部纹理质量

4. 训练GAN,优化对抗+内容+可选感知损失

  • train.py实现完整训练循环

  • 交替训练判别器和生成器:先优化D再优化G

  • 综合三种损失:

    • 对抗损失:促使生成图像骗过判别器
    • 内容损失(MSE):保证像素级相似性
    • 感知损失(可选):基于VGG特征,提升视觉质量

5. 验证阶段评估PSNR/SSIM

  • 每个epoch结束后在测试集上评估模型性能

  • 计算两个关键指标:

    • PSNR(峰值信噪比):评估整体重建质量
    • SSIM(结构相似度):评估结构和纹理保留程度
  • 保存SSIM值最高的模型作为最佳模型

6. 单图推理完成修复

  • 使用inference.py加载训练好的生成器模型
  • 对单张老化图像进行前向传播,得到修复结果
  • 支持批量处理多张图像的扩展功能

详细使用步骤

1. 下载数据集

使用download_datasets.py脚本从Kaggle下载风景图像数据集:

python download_datasets.py

下载完成后,数据集会被存储在默认位置(~/.cache/kagglehub/datasets/)。然后您需要将数据集解压并组织成以下结构:

GAN_landscape_img_repair-master/
├── Landscape Classification/
│   ├── Training Data/
│   │   ├── Coast/
│   │   │   ├── Coast-Train (1).jpeg
│   │   │   ├── Coast-Train (2).jpeg
│   │   │   └── ...
│   │   ├── Desert/
│   │   │   ├── Desert-Train (1).jpeg
│   │   │   └── ...
│   │   ├── Forest/
│   │   │   ├── Forest-Train (1).jpeg
│   │   │   └── ...
│   │   ├── Glacier/
│   │   │   ├── Glacier-Train (1).jpeg
│   │   │   └── ...
│   │   └── Mountain/
│   │       ├── Mountain-Train (1).jpeg
│   │       └── ...
│   └── Testing Data/
│       ├── Coast/
│       │   ├── Coast-Test (1).jpeg
│       │   └── ...
│       ├── Desert/
│       ├── Forest/
│       ├── Glacier/
│       └── Mountain/
├── add_noise.py
├── dataset.py
├── download_datasets.py
├── inference.py
├── model.py
├── train.py
└── utils.py

注意事项

  • 如果遇到kagglehub访问问题,需确保已正确配置Kaggle API凭证
  • 您可能需要手动将数据集从下载位置移动到项目目录下
  • 确保类别名称和文件名格式与上述结构一致,否则需修改dataset.py中的路径处理逻辑

2. 生成"磨损"图像

运行add_noise.py脚本,对原始图像添加老化效果:

python add_noise.py

该脚本会自动处理"Landscape Classification"目录中的所有图像,为每张图像应用三种老化效果:

  1. 色彩衰减:adjust_color_randomly函数调整HSV值,主要降低饱和度(15%左右),轻微调整色相(±15°)和亮度(±10%)
  2. 随机高斯噪点:add_random_gaussian_noise函数添加均值为0,标准差在5-25范围内的高斯噪声
  3. 随机划痕:add_scratches函数在图像上添加40条随机位置、随机长度的浅色线条

处理过程显示进度条,每处理一张图像会在对应的"Landscape Classification Noise"目录下保存一份老化版本,保持原目录结构和文件名不变。

处理完成后,目录结构将变为:

GAN_landscape_img_repair-master/
├── Landscape Classification/
│   ├── Training Data/
│   │   └── ...
│   └── Testing Data/
│       └── ...
├── Landscape Classification Noise/   # 新生成的模拟磨损图像目录
│   ├── Training Data/
│   │   ├── Coast/
│   │   │   ├── Coast-Train (1).jpeg  # 老化版本
│   │   │   ├── Coast-Train (2).jpeg
│   │   │   └── ...
│   │   ├── Desert/
│   │   ├── Forest/
│   │   ├── Glacier/
│   │   └── Mountain/
│   └── Testing Data/
│       ├── Coast/
│       ├── Desert/
│       ├── Forest/
│       ├── Glacier/
│       └── Mountain/
├── add_noise.py
├── dataset.py
├── download_datasets.py
├── inference.py
├── model.py
├── train.py
└── utils.py

处理12,000张图像大约需要30-60分钟,取决于CPU性能和图像分辨率。如果需要调整老化效果的强度,可以修改add_noise.py中相应函数的参数:

  • 色彩调整:修改hue_rangesaturation_rangevalue_range参数
  • 噪点强度:修改sigma_range参数
  • 划痕数量:修改num_scratches参数

3. 训练修复模型

使用train.py训练GAN模型:

python train.py --root_dir . --epochs 30 --batch_size 8 --lr 5e-5 --img_size 256 --lambda_content 100.0 --use_perceptual --device cuda --save_dir checkpoints

参数详细说明:

  • --root_dir:项目根目录,包含数据集的位置。默认为当前目录"."

  • --epochs:训练轮数,建议至少30轮获得较好效果,更多轮数可能获得更好结果

  • --batch_size:批量大小,根据GPU内存调整

    • 8GB显存建议设置为8
    • 12GB显存可设置为16
    • 4GB显存建议降至4
  • --lr:学习率,默认5e-5,较低的学习率有助于稳定训练

  • --img_size:训练时的图像大小,默认256×256像素

    • 较大的尺寸可捕获更多细节,但需要更多显存
    • 可选值:128、256、384、512
  • --lambda_content:内容损失权重,控制修复保真度和对抗性的平衡

    • 默认100.0,更高的值会更注重像素级还原
    • 更低的值会增强GAN的创造性,但可能导致细节不准确
  • --use_perceptual:使用VGG感知损失提升视觉质量,略微增加显存占用

  • --device:计算设备,可选"cuda"或"cpu"

  • --save_dir:模型保存目录,默认为"checkpoints"

训练过程中,程序会在每个epoch后评估模型在测试集上的性能,并打印三个关键指标:

  • 生成器损失(G_loss):综合了对抗损失、内容损失和可选的感知损失
  • 判别器损失(D_loss):衡量判别器区分真实和生成图像的能力
  • PSNR和SSIM:客观评价指标,值越高表示修复质量越好

程序会保存SSIM指标最高的模型作为最佳模型。训练完成后,目录结构变为:

GAN_landscape_img_repair-master/
├── Landscape Classification/
│   └── ...
├── Landscape Classification Noise/
│   └── ...
├── checkpoints/                     # 新生成的模型目录
│   └── best_generator.pth           # 最佳生成器模型(约100-200MB)
├── add_noise.py
├── dataset.py
├── download_datasets.py
├── inference.py
├── model.py
├── train.py
└── utils.py

典型的训练时间:

  • GTX 1080Ti:约4-6小时完成30个epoch
  • RTX 3090:约2-3小时完成30个epoch
  • CPU(8核):约40-50小时完成30个epoch

训练过程中可能会观察到:

  • 前5个epoch:PSNR和SSIM快速提升
  • 5-15个epoch:提升速度减缓
  • 15个epoch以后:缓慢改善,主要是细节和纹理的提升

4. 修复单张图像

使用训练好的模型对单张老化图像进行修复:

python inference.py --model_path checkpoints/best_generator.pth --input path/to/noise_image.jpeg --output path/to/repaired_image.png

参数详细说明:

  • --model_path:已训练模型的路径,默认为"checkpoints/best_generator.pth"

  • --input:待修复的老化图像路径,可以是任意尺寸的.jpg/.jpeg/.png图像

  • --output:修复后图像的保存路径,推荐使用.png格式保留所有细节

  • --img_size:处理图像的大小(默认256),可根据需要调整

    • 较大的值(如512)可能获得更好的细节,但处理更慢
    • 无论设置多大,输出图像都会保持与输入相同的分辨率
  • --device:使用"cuda"或"cpu"(默认"cuda")

推理速度参考:

  • GPU(GTX 1080Ti):处理一张1000×1000的图像约0.5秒
  • CPU(Intel i7):处理同样大小的图像约2-3秒

如果你希望批量处理多张图像,可以编写一个简单的脚本调用inference.py中的process_single函数:

import os
from inference import process_single
import torch

# 加载模型
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
G = torch.load('checkpoints/best_generator.pth', map_location=device)
G.to(device).eval()

# 批量处理图像
input_dir = 'path/to/noisy_images'
output_dir = 'path/to/repaired_images'
os.makedirs(output_dir, exist_ok=True)

for img_file in os.listdir(input_dir):
    if img_file.lower().endswith(('.jpg', '.jpeg', '.png')):
        input_path = os.path.join(input_dir, img_file)
        output_path = os.path.join(output_dir, os.path.splitext(img_file)[0] + '.png')
        process_single(input_path, output_path, G, 256, device)
        print(f'已处理: {
     img_file}')

执行后,您的项目目录可能会变为:

GAN_landscape_img_repair-master/
├── Landscape Classification/
├── Landscape Classification Noise/
├── checkpoints/
│   └── best_generator.pth
├── repaired_images/                 # 新生成的修复图像目录
│   ├── image1.png
│   ├── image2.png
│   └── ...
├── add_noise.py
├── dataset.py
├── download_datasets.py
├── inference.py
├── model.py
├── train.py
└── utils.py

各文件功能详解

1. add_noise.py

这个脚本用于模拟老化效果,主要包含三个核心函数:

  • adjust_color_randomly:随机调整图像的HSV值,模拟老照片的色彩退化

    def adjust_color_randomly(image, hue_range=15, saturation_range=0.15, value_range=0.1):
        # 转换为HSV空间
        # 随机调整色相、饱和度和亮度
        # 将图像转回BGR格式
    
  • add_random_gaussian_noise:添加高斯噪声,模拟年代久远的照片中常见的颗粒感

    def add_random_gaussian_noise(image, mean=0, sigma_range=(5, 25)):
        # 生成随机高斯噪声
        # 将噪声添加到图像上
        # 保证像素值在有效范围内
    
  • add_scratches:添加随机划痕,模拟照片表面的机械损伤

    def add_scratches(image, num_scratches=40):
        # 在随机位置生成随机方向的线条
        # 使用浅色(接近白色)表示划痕
        # 添加到图像上
    

此外,还提供了单图处理函数Apply_photo_wear_effect_single和批量处理函数Apply_photos_wear_effect_all,后者还包含完整的目录遍历和进度显示功能。

该文件是整个工作流程的第一步,负责生成训练和测试所需的"老化"图像数据。

2. dataset.py

定义了PyTorch数据集类LandscapeDataset,负责加载成对的老化/干净风景图像:

class LandscapeDataset(Dataset):
    def __init__(self, root_dir, split='train', img_size=256):
        # 初始化路径
        # 查找配对的图像
        # 设置图像变换(调整大小、标准化等)

    def __len__(self):
        # 返回数据集大小

    def __getitem__(self, idx):
        # 根据索引加载图像对
        # 应用变换
        # 返回(noisy, clean)图像对

主要功能包括:

  • 自动查找和配对对应的老化图像和原始图像
  • 图像预处理:调整到指定大小(默认256×256)
  • 标准化:将像素值缩放到[-1, 1]范围
  • 数据增强:训练集可选的随机水平翻转和轻微旋转
  • 按批次提供给训练循环

设计上采用了成对加载机制,确保老化图像和原始图像严格对应,便于监督学习。

3. download_datasets.py

使用kagglehub工具从Kaggle平台下载风景识别数据集:

import kagglehub

# 下载最新版本
path = kagglehub.dataset_download("utkarshsaxenadn/landscape-recognition-image-dataset-12k-images")

print("数据集文件路径:", path)

这个脚本虽然简短,但执行了重要的数据获取任务。它会自动下载和解压数据集,并返回数据集的本地路径。需要注意的是,使用前应确保已安装kagglehub并配置了Kaggle API凭证。

4. inference.py

提供单张图像的推理功能,主要包含:

  • 参数解析函数parse_args,处理命令行参数

  • 图像处理函数process_single

    def process_single(input_path, output_path, G, img_size, device):    # 加载与预处理图像    # 记录原始尺寸    # 送入模型推理    # 后处理生成结果(反标准化等)    # 恢复原始尺寸    # 保存结果
    
  • 主函数main,负责加载模型和调用处理函数

工作流程:

  1. 加载图像并调整大小
  2. 标准化到[-1, 1]范围
  3. 送入生成器模型进行推理
  4. 将输出反标准化回[0, 1]范围
  5. 恢复原始图像尺寸
  6. 保存为指定格式

该脚本设计成可以作为独立工具使用,也可以作为模块导入到其他Python脚本中用于批处理。

5. model.py

定义GAN的网络架构,包含以下主要组件:

  • 基础模块:

    class DownSample(nn.Module):
        # 下采样模块:卷积 + 可选批归一化 + LeakyReLU
    
    class UpSample(nn.Module):
        # 上采样模块:转置卷积 + 可选批归一化 + 可选ReLU
    
  • 生成器:

    class RepairNetGenerator(nn.Module):
        # 多分支U-Net结构
        # 共享编码器(3层)
        # 多路径解码器(3条路径)
        # 初步融合模块
        # 细节增强模块
    
  • 判别器:

    class RepairNetDiscriminator(nn.Module):
        # PatchGAN判别器
        # 接收拼接的输入和目标/生成图像
        # 输出每个图像块的真假判断
    

生成器采用创新的多分支U-Net结构,包括:

  1. 共享编码器:提取多尺度特征
  2. 三个独立解码路径:各自关注不同尺度的重建
  3. 融合模块:结合三条路径的输出
  4. 细节增强:进一步提升局部细节

判别器采用PatchGAN设计,以70×70的感受野判断图像块的真实性,有助于提升局部纹理质量。

6. train.py

实现了GAN的训练循环,主要功能包括:

  • 参数配置和数据加载

  • 网络初始化(生成器和判别器)

  • 损失函数定义(BCE、MSE、可选的VGG感知损失)

  • 优化器设置

  • 训练循环:

    for epoch in range(1, args.epochs+1):    # 训练阶段    for noisy, real in train_loader:        # 判别器更新        # 生成器更新        # 验证阶段    with torch.no_grad():        for noisy, real in test_loader:            # 计算PSNR和SSIM        # 保存最佳模型
    
  • 评估指标计算(PSNR和SSIM)

  • 模型保存

训练采用标准的GAN交替优化策略:

  1. 先训练判别器:最大化真实图像的分数,最小化生成图像的分数
  2. 再训练生成器:最大化生成图像的分数,同时最小化与真实图像的差异

评估使用两个客观指标:

  • PSNR(峰值信噪比):评估整体像素差异
  • SSIM(结构相似度):评估结构和纹理保留程度

模型保存逻辑是保留验证集上SSIM值最高的模型。

7. utils.py

提供基础工具函数:

  • load_image:加载图像并转换为RGB模式

    def load_image(path):
        return Image.open(path).convert('RGB')
    
  • save_image:将张量保存为图像文件

    def save_image(tensor, path):
        # 处理张量:分离、CPU转移
        # 从[-1,1]映射到[0,1]
        # 从[0,1]映射到[0,255]
        # 转换通道顺序并创建PIL图像
        # 保存到指定路径
    

这些工具函数封装了常用的图像处理操作,确保在项目各部分保持一致的图像处理流程。

网络架构设计

生成器架构

本项目的生成器采用了创新的多分支U-Net结构,由以下几个部分组成:

  1. 共享编码器

    • 3层下采样,逐步将输入图像(3×H×W)编码为更深层的特征图
    • 第一层:3→64通道,无批归一化
    • 第二层:64→128通道,带批归一化
    • 第三层:128→256通道,带批归一化
    • 采用LeakyReLU激活函数,斜率0.2
  2. 多分支解码器

    • 分支1:直接从第一层特征上采样到输出尺寸(浅层特征路径)
    • 分支2:从第二层特征经过两次上采样到输出尺寸(中层特征路径)
    • 分支3:从第三层特征经过三次上采样到输出尺寸(深层特征路径)
    • 每个分支独立工作,没有跳跃连接,专注于不同尺度的信息重建
  3. 初步融合模块

    • 将三个分支的输出拼接(concat)
    • 通过两个连续的卷积层(带ReLU和Tanh)融合多尺度信息
    • 将特征通道数从3×输出通道数减少到输出通道数
  4. 细节增强模块

    • 在融合后的结果上再次应用两个卷积层
    • 专注于增强局部细节和边缘
    • 最终输出通过Tanh激活,确保值域在[-1,1]

这种多分支设计的优势:

  • 不同分支可以关注不同类型的图像退化:浅层分支处理噪声,深层分支处理结构
  • 避免了传统U-Net中可能出现的信息损失
  • 细节增强模块相当于残差学习,进一步提升图像质量

判别器架构

判别器采用PatchGAN设计,结构如下:

  • 输入:拼接的条件图像和目标/生成图像(6×H×W)

  • 4层下采样,每层将空间分辨率减半:

    • 第一层:6→64通道,无批归一化
    • 第二层:64→128通道,带批归一化
    • 第三层:128→256通道,带批归一化
    • 第四层:256→512通道,带批归一化
  • 最终层:512→1通道,输出每个位置的判别分数

  • 所有下采样层使用LeakyReLU激活函数

  • </
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值