LowLightEnhancementTest1

Cealivanus Kwan Lv3

基于U-Net的弱光图像增强系统

项目基本结构

1
2
3
4
5
6
7
8
weak_light_enhancement/
├── main.py # 主训练脚本
├── model.py # 模型定义
├── dataset.py # 数据加载器
├── loss.py # 损失函数
├── config.py # 配置文件
├── test_inference.py # 推理测试脚本
└── requirements.txt # 依赖包

使用说明

1. 环境准备
1
pip install -r requirements.txt
2. 数据准备

创建以下目录结构:

1
2
3
4
5
data/
├── train/
│ ├── weak/ # 放置弱光训练图像
│ └── normal/ # 放置对应的正常光图像(监督信号)
└── test/ # 放置测试图像
3. 训练模型
1
python main.py
4. 测试推理
1
python test_inference.py

项目简述

整个系统的核心是一个精心设计的简化版U-Net架构。这个网络结构包含对称的编码器和解码器路径,通过跳跃连接将浅层特征与深层语义信息融合,确保在增强亮度的同时不丢失边缘和纹理细节。编码器部分通过四级下采样逐步提取抽象特征,每级都包含两个卷积层配合批归一化和ReLU激活函数。解码器则通过双线性上采样逐步恢复空间分辨率,并与对应层级的编码器特征拼接,实现多尺度信息的高效利用。

在损失函数设计上,我采用了多任务学习的思路,将像素级L1损失、结构相似性损失、颜色一致性损失和梯度保持损失有机组合。其中SSIM损失专门优化图像的结构相似性,确保增强后的图像在视觉感知上更加自然;颜色损失通过比较通道均值来维持色彩平衡,避免出现色偏问题;梯度损失则利用Sobel算子提取边缘信息,重点保护图像中的重要轮廓特征。这种复合损失函数的设计使得模型在提升亮度的同时,能够全面考虑图像的视觉质量各个方面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
"""
title: 丢失函数
author: Ceazon

"""
import torch
import torch.nn as nn
import torch.nn.functional as F


class SimpleEnhancementLoss(nn.Module):
"""
简化版损失函数,不使用VGG,避免下载问题和KeyError
"""

def __init__(self, device):
super(SimpleEnhancementLoss, self).__init__()
self.device = device

self.weights = {
'pixel': 1.0,
'color': 0.5,
'ssim': 0.5,
'gradient': 0.2
}

def color_loss(self, enhanced, target):
"""颜色一致性损失"""
enhanced_mean = torch.mean(enhanced, dim=[2, 3], keepdim=True)
target_mean = torch.mean(target, dim=[2, 3], keepdim=True)
return F.l1_loss(enhanced_mean, target_mean)

def ssim_loss(self, enhanced, target):
"""结构相似性损失"""
C1 = 0.01 ** 2
C2 = 0.03 ** 2

mu_x = torch.mean(enhanced, dim=[2, 3], keepdim=True)
mu_y = torch.mean(target, dim=[2, 3], keepdim=True)

sigma_x = torch.mean((enhanced - mu_x) ** 2, dim=[2, 3], keepdim=True)
sigma_y = torch.mean((target - mu_y) ** 2, dim=[2, 3], keepdim=True)
sigma_xy = torch.mean((enhanced - mu_x) * (target - mu_y), dim=[2, 3], keepdim=True)

ssim_n = (2 * mu_x * mu_y + C1) * (2 * sigma_xy + C2)
ssim_d = (mu_x ** 2 + mu_y ** 2 + C1) * (sigma_x + sigma_y + C2)

ssim = ssim_n / ssim_d
return 1 - torch.mean(ssim)

def gradient_loss(self, enhanced, target):
"""梯度损失,保持边缘信息"""
enhanced_gray = torch.mean(enhanced, dim=1, keepdim=True)
target_gray = torch.mean(target, dim=1, keepdim=True)

# Sobel算子计算梯度
sobel_x = torch.tensor([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]],
dtype=torch.float32, device=self.device).view(1, 1, 3, 3)
sobel_y = torch.tensor([[-1, -2, -1], [0, 0, 0], [1, 2, 1]],
dtype=torch.float32, device=self.device).view(1, 1, 3, 3)

enhanced_grad_x = F.conv2d(enhanced_gray, sobel_x, padding=1)
enhanced_grad_y = F.conv2d(enhanced_gray, sobel_y, padding=1)
target_grad_x = F.conv2d(target_gray, sobel_x, padding=1)
target_grad_y = F.conv2d(target_gray, sobel_y, padding=1)

grad_loss = F.l1_loss(enhanced_grad_x, target_grad_x) + F.l1_loss(enhanced_grad_y, target_grad_y)
return grad_loss

def forward(self, enhanced, target):
# 像素级L1损失
pixel_loss = F.l1_loss(enhanced, target)

# 颜色损失
color_loss = self.color_loss(enhanced, target)

# SSIM损失
ssim_loss = self.ssim_loss(enhanced, target)

# 梯度损失
gradient_loss = self.gradient_loss(enhanced, target)

# 总损失
total_loss = (self.weights['pixel'] * pixel_loss +
self.weights['color'] * color_loss +
self.weights['ssim'] * ssim_loss +
self.weights['gradient'] * gradient_loss)

# 返回统一的损失字典(确保所有键都存在)
loss_dict = {
'total': total_loss.item(),
'pixel': pixel_loss.item(),
'color': color_loss.item(),
'ssim': ssim_loss.item(),
'gradient': gradient_loss.item()
}

return total_loss, loss_dict

数据加载模块采用了灵活的管道设计,支持自动的图像尺寸调整、张量转换和归一化处理。数据集组织采用弱光-正常光图像对的形式,为监督学习提供准确的训练目标。在训练过程中,我引入了TensorBoard进行实时监控,可以直观地观察各项损失的变化趋势和训练进度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
"""
title: 数据加载器
author: Ceazon

"""

import os
import torch
from torch.utils.data import Dataset, DataLoader
from PIL import Image
import torchvision.transforms as transforms
import cv2
import numpy as np


class WeakLightDataset(Dataset):
def __init__(self, weak_dir, normal_dir, transform=None, image_size=256):
self.weak_dir = weak_dir
self.normal_dir = normal_dir
self.image_size = image_size

# 获取图像文件名
self.weak_images = sorted([f for f in os.listdir(weak_dir) if f.endswith(('.png', '.jpg', '.jpeg'))])
self.normal_images = sorted([f for f in os.listdir(normal_dir) if f.endswith(('.png', '.jpg', '.jpeg'))])

# 基础数据变换
if transform is None:
self.transform = transforms.Compose([
transforms.Resize((image_size, image_size)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) # 归一化到 [-1, 1]
])
else:
self.transform = transform

def __len__(self):
return min(len(self.weak_images), len(self.normal_images))

def __getitem__(self, idx):
# 加载弱光图像
weak_path = os.path.join(self.weak_dir, self.weak_images[idx])
weak_img = Image.open(weak_path).convert('RGB')

# 加载正常光图像(监督信号)
normal_path = os.path.join(self.normal_dir, self.normal_images[idx])
normal_img = Image.open(normal_path).convert('RGB')

# 应用变换
weak_tensor = self.transform(weak_img)
normal_tensor = self.transform(normal_img)

return weak_tensor, normal_tensor


def create_data_loader(config):
"""创建数据加载器"""
dataset = WeakLightDataset(
weak_dir=config.train_weak_dir,
normal_dir=config.train_normal_dir,
image_size=config.image_size
)

dataloader = DataLoader(
dataset,
batch_size=config.batch_size,
shuffle=True,
num_workers=2
)

return dataloader

推理阶段的设计充分考虑了实用性,模型支持任意尺寸的输入图像,自动进行预处理和后处理操作。增强后的图像不仅亮度得到提升,更重要的是保持了自然的色彩分布和清晰的细节表现,特别适合安防监控、夜间摄影等实际应用场景。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
"""
title: 推理测试脚本
author: Ceazon

"""

import torch
import os
import cv2
import numpy as np
from PIL import Image
import torchvision.transforms as transforms
from model import create_model
from config import Config


def enhance_single_image(model, image_path, output_path, device, image_size=256):
"""增强单张图像"""
# 加载和预处理图像
image = Image.open(image_path).convert('RGB')
original_size = image.size

transform = transforms.Compose([
transforms.Resize((image_size, image_size)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])

image_tensor = transform(image).unsqueeze(0).to(device)

# 推理
model.eval()
with torch.no_grad():
enhanced_tensor = model(image_tensor)

# 后处理:反归一化并转换为numpy
enhanced_tensor = enhanced_tensor.squeeze(0).cpu()
enhanced_tensor = (enhanced_tensor + 1) / 2 # [-1,1] -> [0,1]
enhanced_np = enhanced_tensor.permute(1, 2, 0).numpy()
enhanced_np = (enhanced_np * 255).astype(np.uint8)

# 调整回原始尺寸并保存
enhanced_pil = Image.fromarray(enhanced_np)
enhanced_pil = enhanced_pil.resize(original_size, Image.Resampling.LANCZOS)
enhanced_pil.save(output_path)

print(f"增强后的图像已保存: {output_path}")


def main():
config = Config()
device = torch.device(config.device)

# 加载训练好的模型
model = create_model().to(device)
model_path = os.path.join(config.save_dir, 'final_model.pth')

if os.path.exists(model_path):
model.load_state_dict(torch.load(model_path, map_location=device))
print("模型加载成功!")
else:
print("未找到训练好的模型,请先运行训练脚本")
return

# 测试目录中的所有图像
test_dir = config.test_dir
output_dir = "enhanced_results"
os.makedirs(output_dir, exist_ok=True)

if os.path.exists(test_dir):
for filename in os.listdir(test_dir):
if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
input_path = os.path.join(test_dir, filename)
output_path = os.path.join(output_dir, f"enhanced_{filename}")

enhance_single_image(model, input_path, output_path, device, config.image_size)
else:
print(f"测试目录不存在: {test_dir}")


if __name__ == "__main__":
main()

训练数据集来源

数据集-OpenDataLab

训练结果

2025.11.23运行结果小计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
(.venv) PS X:\1LowLightImaging\LowLightEnhancementTest1> python main.py
使用CPU
开始训练...
Epoch 1/50: 100%|██████████████████████████████████████████████████████| 250/250 [12:00<00:00, 2.88s/it, Loss=0.8483, Pixel=0.2935, SSIM=0.6660, Color=0.2563]
Epoch [1/50], 平均损失: 0.7933
Epoch 2/50: 100%|██████████████████████████████████████████████████████| 250/250 [12:17<00:00, 2.95s/it, Loss=0.4654, Pixel=0.1679, SSIM=0.3750, Color=0.1090]
Epoch [2/50], 平均损失: 0.7065
Epoch 3/50: 100%|██████████████████████████████████████████████████████| 250/250 [11:49<00:00, 2.84s/it, Loss=0.5471, Pixel=0.1682, SSIM=0.5130, Color=0.1355]
Epoch [3/50], 平均损失: 0.6788
Epoch 4/50: 100%|██████████████████████████████████████████████████████| 250/250 [11:52<00:00, 2.85s/it, Loss=0.3635, Pixel=0.1391, SSIM=0.2530, Color=0.0772]
Epoch [4/50], 平均损失: 0.6897
Epoch 5/50: 100%|██████████████████████████████████████████████████████| 250/250 [12:17<00:00, 2.95s/it, Loss=0.7517, Pixel=0.2841, SSIM=0.5601, Color=0.2722]
Epoch [5/50], 平均损失: 0.6952
模型已保存: checkpoints\model_epoch_5.pth
Epoch 6/50: 100%|██████████████████████████████████████████████████████| 250/250 [13:32<00:00, 3.25s/it, Loss=0.4852, Pixel=0.1922, SSIM=0.3064, Color=0.1449]
Epoch [6/50], 平均损失: 0.6575
Epoch 7/50: 100%|██████████████████████████████████████████████████████| 250/250 [14:07<00:00, 3.39s/it, Loss=0.6137, Pixel=0.1620, SSIM=0.6454, Color=0.1299]
Epoch [7/50], 平均损失: 0.6581
Epoch 8/50: 100%|██████████████████████████████████████████████████████| 250/250 [11:41<00:00, 2.81s/it, Loss=0.5953, Pixel=0.2345, SSIM=0.3729, Color=0.2199]
Epoch [8/50], 平均损失: 0.6480
Epoch 9/50: 100%|██████████████████████████████████████████████████████| 250/250 [11:50<00:00, 2.84s/it, Loss=0.5371, Pixel=0.1628, SSIM=0.5241, Color=0.1415]
Epoch [9/50], 平均损失: 0.6386
Epoch 10/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:23<00:00, 2.97s/it, Loss=0.6540, Pixel=0.2281, SSIM=0.5344, Color=0.2072]
Epoch [10/50], 平均损失: 0.6292
模型已保存: checkpoints\model_epoch_10.pth
Epoch 11/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:18<00:00, 2.95s/it, Loss=0.6679, Pixel=0.2032, SSIM=0.6354, Color=0.1698]
Epoch [11/50], 平均损失: 0.6313
Epoch 12/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:28<00:00, 2.99s/it, Loss=0.5549, Pixel=0.2019, SSIM=0.4569, Color=0.1175]
Epoch [12/50], 平均损失: 0.6333
Epoch 13/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:08<00:00, 2.91s/it, Loss=0.7904, Pixel=0.2187, SSIM=0.8591, Color=0.1526]
Epoch [13/50], 平均损失: 0.6282
Epoch 14/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:53<00:00, 2.85s/it, Loss=0.8170, Pixel=0.3041, SSIM=0.6440, Color=0.2851]
Epoch [14/50], 平均损失: 0.6216
Epoch 15/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:15<00:00, 2.94s/it, Loss=0.9742, Pixel=0.2616, SSIM=1.0505, Color=0.2337]
Epoch [15/50], 平均损失: 0.6210
模型已保存: checkpoints\model_epoch_15.pth
Epoch 16/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:45<00:00, 2.82s/it, Loss=0.7377, Pixel=0.2339, SSIM=0.6444, Color=0.2245]
Epoch [16/50], 平均损失: 0.6097
Epoch 17/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:39<00:00, 2.80s/it, Loss=0.4855, Pixel=0.2083, SSIM=0.3328, Color=0.1321]
Epoch [17/50], 平均损失: 0.6094
Epoch 18/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:07<00:00, 2.91s/it, Loss=0.5712, Pixel=0.1896, SSIM=0.5141, Color=0.1224]
Epoch [18/50], 平均损失: 0.6238
Epoch 19/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:42<00:00, 2.81s/it, Loss=0.4439, Pixel=0.1738, SSIM=0.3200, Color=0.1197]
Epoch [19/50], 平均损失: 0.6128
Epoch 20/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:09<00:00, 2.92s/it, Loss=0.5439, Pixel=0.1402, SSIM=0.6391, Color=0.0879]
Epoch [20/50], 平均损失: 0.6032
模型已保存: checkpoints\model_epoch_20.pth
Epoch 21/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:43<00:00, 2.81s/it, Loss=0.3819, Pixel=0.1400, SSIM=0.2576, Color=0.0998]
Epoch [21/50], 平均损失: 0.6104
Epoch 22/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:42<00:00, 2.81s/it, Loss=0.4719, Pixel=0.1804, SSIM=0.3357, Color=0.1461]
Epoch [22/50], 平均损失: 0.6071
Epoch 23/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:47<00:00, 2.83s/it, Loss=0.3669, Pixel=0.1519, SSIM=0.2029, Color=0.1059]
Epoch [23/50], 平均损失: 0.6146
Epoch 24/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:43<00:00, 2.81s/it, Loss=0.3853, Pixel=0.1435, SSIM=0.2938, Color=0.1093]
Epoch [24/50], 平均损失: 0.6022
Epoch 25/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:27<00:00, 2.99s/it, Loss=0.4153, Pixel=0.1416, SSIM=0.3560, Color=0.0951]
Epoch [25/50], 平均损失: 0.6010
模型已保存: checkpoints\model_epoch_25.pth
Epoch 26/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:56<00:00, 2.87s/it, Loss=0.3997, Pixel=0.1333, SSIM=0.3410, Color=0.0960]
Epoch [26/50], 平均损失: 0.5873
Epoch 27/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:55<00:00, 2.86s/it, Loss=0.8101, Pixel=0.3001, SSIM=0.6643, Color=0.2615]
Epoch [27/50], 平均损失: 0.5867
Epoch 28/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:53<00:00, 2.85s/it, Loss=0.7385, Pixel=0.2320, SSIM=0.7444, Color=0.1896]
Epoch [28/50], 平均损失: 0.5910
Epoch 29/50: 100%|█████████████████████████████████████████████████████| 250/250 [33:20<00:00, 8.00s/it, Loss=0.6486, Pixel=0.2622, SSIM=0.4462, Color=0.1762]
Epoch [29/50], 平均损失: 0.5969
Epoch 30/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:28<00:00, 3.00s/it, Loss=0.6403, Pixel=0.2340, SSIM=0.5194, Color=0.1815]
Epoch [30/50], 平均损失: 0.5869
模型已保存: checkpoints\model_epoch_30.pth
Epoch 31/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:56<00:00, 2.86s/it, Loss=0.4417, Pixel=0.1907, SSIM=0.2741, Color=0.1328]
Epoch [31/50], 平均损失: 0.5820
Epoch 32/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:00<00:00, 2.88s/it, Loss=0.4848, Pixel=0.1526, SSIM=0.4477, Color=0.1153]
Epoch [32/50], 平均损失: 0.5936
Epoch 33/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:13<00:00, 2.94s/it, Loss=0.3727, Pixel=0.1471, SSIM=0.2684, Color=0.0778]
Epoch [33/50], 平均损失: 0.5758
Epoch 34/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:47<00:00, 2.83s/it, Loss=0.7852, Pixel=0.2791, SSIM=0.6393, Color=0.2493]
Epoch [34/50], 平均损失: 0.5752
Epoch 35/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:49<00:00, 2.84s/it, Loss=0.5436, Pixel=0.1767, SSIM=0.4980, Color=0.1459]
Epoch [35/50], 平均损失: 0.5751
模型已保存: checkpoints\model_epoch_35.pth
Epoch 36/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:48<00:00, 2.84s/it, Loss=0.7050, Pixel=0.2337, SSIM=0.6425, Color=0.2013]
Epoch [36/50], 平均损失: 0.5854
Epoch 37/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:52<00:00, 2.85s/it, Loss=0.6237, Pixel=0.2212, SSIM=0.4791, Color=0.1972]
Epoch [37/50], 平均损失: 0.5793
Epoch 38/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:14<00:00, 2.94s/it, Loss=0.5081, Pixel=0.1675, SSIM=0.4498, Color=0.1130]
Epoch [38/50], 平均损失: 0.5837
Epoch 39/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:52<00:00, 2.85s/it, Loss=0.5661, Pixel=0.1688, SSIM=0.5630, Color=0.1357]
Epoch [39/50], 平均损失: 0.5684
Epoch 40/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:51<00:00, 2.84s/it, Loss=0.3492, Pixel=0.1239, SSIM=0.2821, Color=0.0926]
Epoch [40/50], 平均损失: 0.5621
模型已保存: checkpoints\model_epoch_40.pth
Epoch 41/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:02<00:00, 2.89s/it, Loss=0.7467, Pixel=0.2464, SSIM=0.6612, Color=0.2358]
Epoch [41/50], 平均损失: 0.5739
Epoch 42/50: 100%|█████████████████████████████████████████████████████| 250/250 [18:55<00:00, 4.54s/it, Loss=0.6710, Pixel=0.2475, SSIM=0.5524, Color=0.1679]
Epoch [42/50], 平均损失: 0.5621
Epoch 43/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:06<00:00, 2.91s/it, Loss=0.4863, Pixel=0.1543, SSIM=0.4490, Color=0.1294]
Epoch [43/50], 平均损失: 0.5787
Epoch 44/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:40<00:00, 2.80s/it, Loss=0.6082, Pixel=0.2096, SSIM=0.5313, Color=0.1611]
Epoch [44/50], 平均损失: 0.5604
Epoch 45/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:40<00:00, 2.80s/it, Loss=0.6087, Pixel=0.2249, SSIM=0.4806, Color=0.1768]
Epoch [45/50], 平均损失: 0.5657
模型已保存: checkpoints\model_epoch_45.pth
Epoch 46/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:41<00:00, 2.81s/it, Loss=0.6111, Pixel=0.1542, SSIM=0.6984, Color=0.1170]
Epoch [46/50], 平均损失: 0.5714
Epoch 47/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:46<00:00, 2.83s/it, Loss=0.9169, Pixel=0.2665, SSIM=0.9167, Color=0.2502]
Epoch [47/50], 平均损失: 0.5781
Epoch 48/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:06<00:00, 2.91s/it, Loss=0.6007, Pixel=0.2049, SSIM=0.5396, Color=0.1573]
Epoch [48/50], 平均损失: 0.5612
Epoch 49/50: 100%|█████████████████████████████████████████████████████| 250/250 [11:44<00:00, 2.82s/it, Loss=0.8744, Pixel=0.2294, SSIM=0.9773, Color=0.1978]
Epoch [49/50], 平均损失: 0.5508
Epoch 50/50: 100%|█████████████████████████████████████████████████████| 250/250 [12:09<00:00, 2.92s/it, Loss=0.5267, Pixel=0.1442, SSIM=0.5780, Color=0.1052]
Epoch [50/50], 平均损失: 0.5608
模型已保存: checkpoints\model_epoch_50.pth
最终模型已保存: checkpoints\final_model.pth
(.venv) PS X:\1LowLightImaging\LowLightEnhancementTest1> python test_inference.py
使用CPU
模型加载成功!
增强后的图像已保存: enhanced_results\enhanced_489.png
增强后的图像已保存: enhanced_results\enhanced_490.png
增强后的图像已保存: enhanced_results\enhanced_469.png
增强后的图像已保存: enhanced_results\enhanced_470.png
增强后的图像已保存: enhanced_results\enhanced_471.png
增强后的图像已保存: enhanced_results\enhanced_472.png
增强后的图像已保存: enhanced_results\enhanced_478.png
增强后的图像已保存: enhanced_results\enhanced_479.png
增强后的图像已保存: enhanced_results\enhanced_480.png
增强后的图像已保存: enhanced_results\enhanced_481.png
增强后的图像已保存: enhanced_results\enhanced_487.png
增强后的图像已保存: enhanced_results\enhanced_488.png
(.venv) PS X:\1LowLightImaging\LowLightEnhancementTest1>
  • 标题: LowLightEnhancementTest1
  • 作者: Cealivanus Kwan
  • 创建于 : 2025-11-23 21:55:57
  • 更新于 : 2025-11-23 22:12:30
  • 链接: https://redefine.ohevan.com/2025/11/23/LowLightEnhancementTest1/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
目录
LowLightEnhancementTest1