Structural Similarity Index
时间: 2024-03-08 20:44:18 浏览: 130
结构相似性指数(Structural Similarity Index,简称SSIM)是一种用于衡量两幅图像之间相似度的指标。它不仅考虑了图像的亮度、对比度和结构信息,还考虑了人眼感知的特性。
SSIM的计算基于以下三个方面:
1. 亮度相似度(Luminance Similarity):衡量图像的亮度信息是否相似。
2. 对比度相似度(Contrast Similarity):衡量图像的对比度信息是否相似。
3. 结构相似度(Structure Similarity):衡量图像的结构信息是否相似。
SSIM的取值范围在0到1之间,值越接近1表示两幅图像越相似,值越接近0表示两幅图像越不相似。
相关问题
采用 PSNR(Peak Signal-to-Noise Ratio)和 SSIM(Structural Similarity Index)两个指标进行评价一个算法,这个算法的功能是将黑白人像照片进行彩色化,给出完整代码
这里是一个简单的彩色化算法,使用PyTorch实现,并且使用PSNR和SSIM两个指标进行评价:
```python
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import transforms, datasets
from torch.utils.data import DataLoader
from PIL import Image
from skimage.measure import compare_psnr, compare_ssim
# 定义彩色化模型
class ColorizationModel(nn.Module):
def __init__(self):
super(ColorizationModel, self).__init__()
self.conv1 = nn.Conv2d(1, 64, kernel_size=3, stride=1, padding=1)
self.conv2 = nn.Conv2d(64, 64, kernel_size=3, stride=2, padding=1)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
self.conv4 = nn.Conv2d(128, 128, kernel_size=3, stride=2, padding=1)
self.conv5 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1)
self.conv6 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
self.conv7 = nn.Conv2d(256, 256, kernel_size=3, stride=2, padding=1)
self.conv8 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1)
self.conv9 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv10 = nn.Conv2d(512, 512, kernel_size=3, stride=2, padding=1)
self.conv11 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv12 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv13 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv14 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv15 = nn.Conv2d(512, 512, kernel_size=3, stride=2, padding=1)
self.conv16 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv17 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv18 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv19 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv20 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv21 = nn.Conv2d(512, 512, kernel_size=3, stride=2, padding=1)
self.conv22 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv23 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv24 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv25 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv26 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
self.conv27 = nn.ConvTranspose2d(512, 256, kernel_size=4, stride=2, padding=1)
self.conv28 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
self.conv29 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
self.conv30 = nn.ConvTranspose2d(256, 128, kernel_size=4, stride=2, padding=1)
self.conv31 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1)
self.conv32 = nn.ConvTranspose2d(128, 64, kernel_size=4, stride=2, padding=1)
self.conv33 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1)
self.conv34 = nn.Conv2d(64, 2, kernel_size=3, stride=1, padding=1)
def forward(self, x):
x = nn.functional.relu(self.conv1(x))
x = nn.functional.relu(self.conv2(x))
x = nn.functional.relu(self.conv3(x))
x = nn.functional.relu(self.conv4(x))
x = nn.functional.relu(self.conv5(x))
x = nn.functional.relu(self.conv6(x))
x = nn.functional.relu(self.conv7(x))
x = nn.functional.relu(self.conv8(x))
x = nn.functional.relu(self.conv9(x))
x = nn.functional.relu(self.conv10(x))
x = nn.functional.relu(self.conv11(x))
x = nn.functional.relu(self.conv12(x))
x = nn.functional.relu(self.conv13(x))
x = nn.functional.relu(self.conv14(x))
x = nn.functional.relu(self.conv15(x))
x = nn.functional.relu(self.conv16(x))
x = nn.functional.relu(self.conv17(x))
x = nn.functional.relu(self.conv18(x))
x = nn.functional.relu(self.conv19(x))
x = nn.functional.relu(self.conv20(x))
x = nn.functional.relu(self.conv21(x))
x = nn.functional.relu(self.conv22(x))
x = nn.functional.relu(self.conv23(x))
x = nn.functional.relu(self.conv24(x))
x = nn.functional.relu(self.conv25(x))
x = nn.functional.relu(self.conv26(x))
x = nn.functional.relu(self.conv27(x))
x = nn.functional.relu(self.conv28(x))
x = nn.functional.relu(self.conv29(x))
x = nn.functional.relu(self.conv30(x))
x = nn.functional.relu(self.conv31(x))
x = nn.functional.relu(self.conv32(x))
x = nn.functional.tanh(self.conv33(x))
x = nn.functional.sigmoid(self.conv34(x))
return x
# 定义训练函数
def train(model, train_loader, criterion, optimizer):
model.train()
for inputs, targets in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()
# 定义测试函数
def test(model, test_loader):
model.eval()
psnr_total = 0
ssim_total = 0
for inputs, targets in test_loader:
outputs = model(inputs)
psnr_total += compare_psnr(targets[0].numpy().transpose(1, 2, 0), outputs[0].detach().numpy().transpose(1, 2, 0), data_range=1)
ssim_total += compare_ssim(targets[0].numpy().transpose(1, 2, 0), outputs[0].detach().numpy().transpose(1, 2, 0), multichannel=True)
psnr_avg = psnr_total / len(test_loader)
ssim_avg = ssim_total / len(test_loader)
return psnr_avg, ssim_avg
# 定义数据集加载函数
def load_data(data_dir, batch_size):
train_transforms = transforms.Compose([
transforms.Resize(256),
transforms.RandomCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
test_transforms = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
train_dataset = datasets.ImageFolder(root=data_dir + '/train', transform=train_transforms)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_dataset = datasets.ImageFolder(root=data_dir + '/test', transform=test_transforms)
test_loader = DataLoader(test_dataset, batch_size=1, shuffle=False)
return train_loader, test_loader
# 设置超参数
data_dir = './data'
batch_size = 64
lr = 0.001
num_epochs = 10
# 加载数据
train_loader, test_loader = load_data(data_dir, batch_size)
# 初始化模型、损失函数和优化器
model = ColorizationModel()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=lr)
# 训练模型
for epoch in range(num_epochs):
train(model, train_loader, criterion, optimizer)
psnr, ssim = test(model, test_loader)
print('Epoch [{}/{}], PSNR: {:.4f}, SSIM: {:.4f}'.format(epoch+1, num_epochs, psnr, ssim))
# 保存模型
torch.save(model.state_dict(), 'colorization_model.pth')
```
注:此代码仅为示例,实际应用中还可以进行更多的优化和改进。
采用 PSNR(Peak Signal-to-Noise Ratio)和 SSIM(Structural Similarity Index)两个指标对一个算法进行评价,这个算法的功能是将黑白人像照片进行彩色化,给出完整的评价代码
以下是使用 Python 语言实现的 PSNR 和 SSIM 评价代码:
```python
import cv2
import numpy as np
def psnr(img1, img2):
mse = np.mean((img1 - img2) ** 2)
if mse == 0:
return float('inf')
max_pixel = 255.0
psnr = 20 * np.log10(max_pixel / np.sqrt(mse))
return psnr
def ssim(img1, img2):
C1 = (0.01 * 255) ** 2
C2 = (0.03 * 255) ** 2
img1 = img1.astype(np.float64)
img2 = img2.astype(np.float64)
kernel = cv2.getGaussianKernel(11, 1.5)
window = np.outer(kernel, kernel.transpose())
mu1 = cv2.filter2D(img1, -1, window)[5:-5, 5:-5]
mu2 = cv2.filter2D(img2, -1, window)[5:-5, 5:-5]
mu1_sq = mu1 ** 2
mu2_sq = mu2 ** 2
mu1_mu2 = mu1 * mu2
sigma1_sq = cv2.filter2D(img1 ** 2, -1, window)[5:-5, 5:-5] - mu1_sq
sigma2_sq = cv2.filter2D(img2 ** 2, -1, window)[5:-5, 5:-5] - mu2_sq
sigma12 = cv2.filter2D(img1 * img2, -1, window)[5:-5, 5:-5] - mu1_mu2
ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2))
return np.mean(ssim_map)
# 读取原始黑白照片和彩色化后的照片
img1 = cv2.imread('grayscale_photo.jpg')
img2 = cv2.imread('colorized_photo.jpg')
# 将图像转换为 YUV 格式
img1_yuv = cv2.cvtColor(img1, cv2.COLOR_BGR2YUV)
img2_yuv = cv2.cvtColor(img2, cv2.COLOR_BGR2YUV)
# 取出 Y 通道
img1_y = img1_yuv[:,:,0]
img2_y = img2_yuv[:,:,0]
# 计算 PSNR 和 SSIM
print("PSNR:", psnr(img1_y, img2_y))
print("SSIM:", ssim(img1_y, img2_y))
```
其中,`grayscale_photo.jpg` 是原始的黑白人像照片,`colorized_photo.jpg` 是使用算法彩色化后的照片。可以将两张照片放在同一目录下,并将代码保存为 `.py` 文件,然后在命令行中运行该文件即可输出 PSNR 和 SSIM 的值。
阅读全文