python 图像相似性评估

简介: 相似性经常通过距离的方式来度量,但图像是高纬度的数据,而且图像相似性判断和人类的主观感受存在一定的关系。本文针对图像相似性,梳理了传统的经典算法和基于感知的深度学习方法【2月更文挑战第7天】

python 图像相似性评估

1. 图像相似性

在计算机视觉任务或者图像处理中,常常需要计算图像之间的相似性。特别的,图像相似性经常会用在如图像超分重建,恢复,去噪等任务的质量评估上。

相似性经常通过距离的方式来度量,但图像是高纬度的数据,而且图像相似性判断和人类的主观感受存在一定的关系。本文针对图像相似性,梳理了传统的经典算法和基于感知的深度学习方法,主要方法如下:

  • 峰值信噪比 PSNR
  • 结构化相似度 SSIM
  • 可学习的感知图像相似度 LPIPS

2. 方法

2.1 PSNR

PSNR全名Peak Signal-to-Noise Ratio 即峰值信噪比,是传统的基于像素级别的图像相似性比较。从下面公式(X和Y是两幅图)可知,PSNR是像素的均方误差后取对数,指标上,PSNR越大越相似。公式中n一般取8,即一副图用8比特表示,即图像的像素值范围为[0-255]。

yyq-2021-10-30-23-03-44.png

我们来看下PSNR的效果,第一张图为原图,后面依次是扭曲失真,模糊,jpeg压缩,噪声,对比度亮度调整以及饱和度失真:

from skimage.metrics import structural_similarity as ssim
from skimage.metrics import peak_signal_noise_ratio  as psnr
from imgaug import augmenters as iaa
import numpy as np
import matplotlib.pyplot as plt
import cv2

test_img = cv2.cvtColor(cv2.imread('./cat.png'), cv2.COLOR_BGR2RGB)

blur_aug = iaa.GaussianBlur(sigma=10)
blur_img = blur_aug.augment_image(test_img)

psnr_value = psnr(test_img, blur_img)

yyq-2021-10-30-22-19-33.png

从上图可知,psnr对像素偏差影响较大,对模糊这种人类感知差的反而值越好。

2.2 SSIM

PSNR简单粗暴,有计算效率高的特点,但是与人类感知的视觉质量不太匹配。SSIM是2004年Image quality assessment: from error visibility to structural
similarity提出的基于结构化的图像质量评估方法。SSIM从亮度、对比度、结构三个方面度量图像相似性。SSIM取值范围[0, 1],值越大,表示图像失真越小,越相似。

SSIM的计算过程可以分为三个部分:亮度、对比度、结构。

  • 亮度:以灰度值的平均值作为亮度测量

    yyq-2021-10-30-23-00-51.png

  • 对比度:以灰度值的方差作为对比度测量

    yyq-2021-10-30-23-01-24.png

  • 结构:以像素值的分布来做结构测量

    yyq-2021-10-30-23-02-01.png

综合ssim值为:
yyq-2021-10-30-23-03-08.png

yyq-2021-10-30-23-03-44.png

其中C1、C2、C3为常数,避免分母接近于0时造成的不稳定性。

在实现过程中,一张图以小尺寸进行滑窗然后计算ssim后,然后取均值,会比较有效。

我们来看下SSIM的效果,第一张图为原图,后面依次是扭曲失真,模糊,jpeg压缩,噪声,对比度亮度调整以及饱和度失真。

from skimage.metrics import structural_similarity as ssim
from skimage.metrics import peak_signal_noise_ratio  as psnr
from imgaug import augmenters as iaa
import numpy as np
import matplotlib.pyplot as plt
import cv2

test_img = cv2.cvtColor(cv2.imread('./cat.png'), cv2.COLOR_BGR2RGB)

noise_aug = iaa.AdditiveGaussianNoise(scale=0.2*255)
noise_img = noise_aug.augment_image(test_img)

ssim_value = ssim(test_img, noise_img, multichannel=True)

yyq-2021-10-30-22-22-39.png

从上图可知,相比psnr, ssmi对于亮度和对比度有一定的鲁棒性,但是相对来说模糊也不能很好的体现人类感知效果。

2.3 LPIPS

虽然SSIM也是基于一种感知的度量方法,但是构建人类感知度量是一个挑战,图像相似的感知因素是复杂多变的:结构,上下文等。随着深度学习的发展,由于卷积神经网络高效的提取特征的能力,从语义上评估图像相似性成为可能。The Unreasonable Effectiveness of Deep Features as a Perceptual Metric 这篇文章提出了基于可学习的感知图像相似度量方法LPIPS。

LPIPS通过构建大量的评估图像数据集(Berkeley-Adobe Perceptual Patch Similarity Dataset 简称(BAPPS))来训练深度的感知度量方法。

LPIPS主要的贡献在于如何构建BAPPS,或者说如何获得人类感知的评价, 有了评价值才能训练模型,否则一切免谈。LPIPS首先基于参考图(原图)生成很多失真的图片如模糊,噪声,对比度饱和度变化等,也有基于CNN如去噪,超分,色彩增强等方法生成的图片,在此基础上,基于两种标准找不同人来对参考图和失真进行判断,标准如下:

  • 2AFC(two alternative forced choice):给出两种不同失真操作,挑选出和参考图(原始图)最相近的图,方法中选取了小的区域(64x64)进行判断,有利于局部感知。
  • Just noticeable differences (JND):给出两张图,只判别是否是相同还是不同

数据集构建完成之后,就要搭建可训练的网络。已知x是参考图,x0,x1是失真操作之后的图,由下图可知:

  • 计算x和x0的感知距离d0(同理x和x1距离为d1):先通过特征提取网络F(可以是VGG,AlexNet,SqueezeNet),提取x和x0的各层特征,并作差值,然后乘以一个可学习的权重w,最后进行全局平均得到d0
    yyq-2021-10-23-21-16-56.png
  • 训练一个简单的网络来拟合两种判断d0和d1,与人为判断标准h(即gt)

yyq-2021-10-21-23-31-02.png

注意的是,w和简单网络G都是训练学习的,特征提取网络F可根据预训练网络固定,也可微调学习

官方github(https://www.github.com/richzhang/PerceptualSimilarity) 提供了可直接使用的预训练模型,我们来试下对比效果 lpips值越小越好,0表示完全一致。 第一张图为原图,后面依次是扭曲失真,模糊,jpeg压缩,噪声,对比度亮度调整以及饱和度失真。

pip install lpips
import lpips

loss_fn = lpips.LPIPS(net='alex',version='0.1')
use_gpu = True
path0 = './cat.png'
path1 = './noise_cat.png'
if(use_gpu):
    loss_fn.cuda()

# Load images
img0 = lpips.im2tensor(lpips.load_image(path0)) # RGB image from [-1,1]
img1 = lpips.im2tensor(lpips.load_image(path1))

if(use_gpu):
    img0 = img0.cuda()
    img1 = img1.cuda()

# Compute distance
lpips_value = loss_fn.forward(img0, img1)

yyq-2021-10-30-22-44-48.png

从lpips的值可知,相对细微的扭曲(2),亮度(6)和对比度(7)都符合人体感知,模糊也处理可接受的范围。

3. 总结

本文分享了图像相似性评估中三种不同但常用的原理和具体使用,希望对你有帮助,欢迎交流(weixin:@mintel)。总结如下:

  • PSNR峰值信噪比:简单速度快,最常见的方式,但与人类感知存在差距,越大越好
  • SSIM:亮度、对比度、结构的感知,越大越好
  • LPIPS:基于深度学习的感知相似性评估,重在基于2AFC和JND的训练数据构建,和常规网络模型,符合人类感知,越小越好
目录
相关文章
|
2月前
|
Python
python用鼠标获取图像任一点的坐标和像素值
python用鼠标获取图像任一点的坐标和像素值
44 1
|
2月前
|
机器学习/深度学习 算法 PyTorch
python手把手搭建图像多分类神经网络-代码教程(手动搭建残差网络、mobileNET)
python手把手搭建图像多分类神经网络-代码教程(手动搭建残差网络、mobileNET)
46 0
|
2月前
|
机器学习/深度学习 算法 数据可视化
python/matlab图像去雾/去雨综述
python/matlab图像去雾/去雨综述
39 0
|
2月前
|
机器学习/深度学习 算法 计算机视觉
如何利用Python实现图像识别中的目标检测
Python是一种功能强大的编程语言,可以用于图像识别中的目标检测。本文将介绍如何使用Python和OpenCV库实现目标检测的基本原理和方法,并提供实用的代码示例。
|
7天前
|
数据可视化 Python
Python模型评估与选择:面试必备知识点
【4月更文挑战第17天】本文深入探讨了Python模型评估与选择在面试中的关键点,包括性能度量、过拟合与欠拟合识别、模型比较与选择、模型融合和偏差-方差权衡。强调了避免混淆评估指标、忽视模型验证和盲目追求高复杂度模型的常见错误,并提供相关代码示例,如交叉验证、网格搜索和超参数调优。通过理解这些概念和技巧,可在面试中展示出色的数据科学能力。
31 12
|
8天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
使用Python构建简单的图像识别应用
本文将介绍如何利用Python语言及其相关库来构建一个简单但功能强大的图像识别应用。通过结合OpenCV和深度学习模型,我们将展示如何实现图像的特征提取和分类,从而实现对图像中物体的自动识别和分类。无需复杂的算法知识,只需一些基本的Python编程技巧,你也可以轻松地创建自己的图像识别应用。
|
1月前
|
机器学习/深度学习 人工智能 TensorFlow
用Python实现基本图像识别
用Python实现基本图像识别
20 0
|
1月前
|
计算机视觉 Python
Python生成图像
Python生成图像
19 0
|
2月前
|
C++ 计算机视觉 Python
【Py调用C++】使用使用python调用C++生成dll处理图像(OPENCV)
【Py调用C++】使用使用python调用C++生成dll处理图像(OPENCV)
38 0
【Py调用C++】使用使用python调用C++生成dll处理图像(OPENCV)
|
2月前
|
机器学习/深度学习 数据采集 算法
Python中的机器学习入门:从数据预处理到模型评估
Python中的机器学习入门:从数据预处理到模型评估
195 35