当前位置:网站首页>图像增强评价指标学习之——结构相似性SSIM
图像增强评价指标学习之——结构相似性SSIM
2022-07-28 05:17:00 【qq_46165876】
SSIM(structural similarity index),结构相似性,是一种衡量两幅图像相似度的指标。该指标首先由德州大学奥斯丁分校的图像和视频工程实验室(Laboratory for Image and Video Engineering)提出。SSIM使用的两张图像中,一张为未经压缩的无失真图像,另一张为失真后的图像。
作为结构相似性理论的实现,结构相似度指数从图像组成的角度将结构信息定义为独于亮度、对比度的,反映场景中物体结构的属性,并将失真建模为亮度、对比度和结构三个不同因素的组合。用均值作为亮度的估计,标准差作为对比度的估计,协方差作为结构相似度程度的度量。
如上为百度百科的解释,关于对应的公式百科也有。
SSIM属于全参考图像质量评价指标。非常尴尬的是最开始我一直把参考图像当成了原图。
后来一想,理论上SSIM是越接近1越好i,但用原始的低照度图像来算的话,不处理是1,越处理越低,这就肯定不对呀,我就详细看了一眼人家官方代码上的注释。
原来这个参考图像指的是认为是完美的图片,意味着做图像增强的话,我们需要数据库里的一组图像,一张需要处理的低照度图像和一张完美的正常图像,然后用我们处理的后的图像与完美图像来计算。
代码及用法分享给大家,万一也有初学者一时搞错了呢。
function [mssim, ssim_map] = ssim(img1, img2, K, window, L)
if (nargin < 2 || nargin > 5)
mssim = -Inf;
ssim_map = -Inf;
return;
end
if (size(img1) ~= size(img2))
mssim = -Inf;
ssim_map = -Inf;
return;
end
[M N] = size(img1);
if (nargin == 2)
if ((M < 11) || (N < 11))
mssim = -Inf;
ssim_map = -Inf;
return
end
window = fspecial('gaussian', 11, 1.5); %
K(1) = 0.01; % default settings
K(2) = 0.03; %
L = 255; %
end
if (nargin == 3)
if ((M < 11) || (N < 11))
mssim = -Inf;
ssim_map = -Inf;
return
end
window = fspecial('gaussian', 11, 1.5);
L = 255;
if (length(K) == 2)
if (K(1) < 0 || K(2) < 0)
mssim = -Inf;
ssim_map = -Inf;
return;
end
else
mssim = -Inf;
ssim_map = -Inf;
return;
end
end
if (nargin == 4)
[H W] = size(window);
if ((H*W) < 4 || (H > M) || (W > N))
mssim = -Inf;
ssim_map = -Inf;
return
end
L = 255;
if (length(K) == 2)
if (K(1) < 0 || K(2) < 0)
mssim = -Inf;
ssim_map = -Inf;
return;
end
else
mssim = -Inf;
ssim_map = -Inf;
return;
end
end
if (nargin == 5)
[H W] = size(window);
if ((H*W) < 4 || (H > M) || (W > N))
mssim = -Inf;
ssim_map = -Inf;
return
end
if (length(K) == 2)
if (K(1) < 0 || K(2) < 0)
mssim = -Inf;
ssim_map = -Inf;
return;
end
else
mssim = -Inf;
ssim_map = -Inf;
return;
end
end
img1 = double(img1);
img2 = double(img2);
% automatic downsampling
f = max(1,round(min(M,N)/256));
%downsampling by f
%use a simple low-pass filter
if(f>1)
lpf = ones(f,f);
lpf = lpf/sum(lpf(:));
img1 = imfilter(img1,lpf,'symmetric','same');
img2 = imfilter(img2,lpf,'symmetric','same');
img1 = img1(1:f:end,1:f:end);
img2 = img2(1:f:end,1:f:end);
end
C1 = (K(1)*L)^2;
C2 = (K(2)*L)^2;
window = window/sum(sum(window));
mu1 = filter2(window, img1, 'valid');
mu2 = filter2(window, img2, 'valid');
mu1_sq = mu1.*mu1;
mu2_sq = mu2.*mu2;
mu1_mu2 = mu1.*mu2;
sigma1_sq = filter2(window, img1.*img1, 'valid') - mu1_sq;
sigma2_sq = filter2(window, img2.*img2, 'valid') - mu2_sq;
sigma12 = filter2(window, img1.*img2, 'valid') - mu1_mu2;
if (C1 > 0 && C2 > 0)
ssim_map = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))./((mu1_sq + mu2_sq + C1).*(sigma1_sq + sigma2_sq + C2));
else
numerator1 = 2*mu1_mu2 + C1;
numerator2 = 2*sigma12 + C2;
denominator1 = mu1_sq + mu2_sq + C1;
denominator2 = sigma1_sq + sigma2_sq + C2;
ssim_map = ones(size(mu1));
index = (denominator1.*denominator2 > 0);
ssim_map(index) = (numerator1(index).*numerator2(index))./(denominator1(index).*denominator2(index));
index = (denominator1 ~= 0) & (denominator2 == 0);
ssim_map(index) = numerator1(index)./denominator1(index);
end
mssim = mean2(ssim_map);
return这个是计算SSIM的子程序。
关于它的使用,直接将一下代码写入主程序就行。
K = [0.05 0.05];
window = ones(8);
L = 100;
[mssim, ssim_map] = ssim(img1, img2, K, window, L);
mssim 其中官方的注解:
input:(1) img1:被比较的第一幅图像
(2) img2:被比较的第二个图像
(3) K:SSIM指数公式中的常数。默认值:K = [0.01 0.03]
(4) window:本地统计窗口。默认widnow为高斯型,由下式给出
window = fspecial('gaussian ',11,1.5);
(5) L:图像的动态范围。默认值:L = 255
output:(1) mssim:两幅图像之间的平均ssim指数值。
如果被比较的图像之一被认为是完美的质量,那么mssim可以被认为是另一个图像的质量度量。
如果img1 = img2,则mssim = 1。
(2) ssim_map:测试图像的ssim指数图。
map的大小取决于输入的图像,实际尺寸取决于窗口大小和下采样因子。边栏推荐
- Mysql基本查询
- 多系统架构设计思考
- 【单例模式】懒汉模式的线程安全问题
- ByteBuffer.position 抛出异常 IllegalArgumentException
- FreeRTOS personal notes - task notification
- Why is MD5 irreversible, but it may also be decrypted by MD5 free decryption website
- mysql 为查询结果增加序号
- About localdatetime in swagger
- IDEA配置 service(Run Dashboard) 服务,多模块同时启动
- repackag failed: Unable to find main class
猜你喜欢

Multi module packaging: package: XXX does not exist

11.< tag-动态规划和子序列, 子数组>lt.115. 不同的子序列 + lt. 583. 两个字符串的删除操作 dbc

Mysql基本查询

Test Development - UI testing in automated testing

Bean的作用域、执行流程、生命周期

ES6 new variable modifiers let and const, new basic data type symbol

Redis 之布隆过滤器

框架一步一步方便使用的流程

Why is MD5 irreversible, but it may also be decrypted by MD5 free decryption website

【SLAM】LVI-SAM解析——综述
随机推荐
Message forwarding mechanism -- save your program from crashing
New methods and features of ES6 built-in objects
You must configure either the server or JDBC driver (via the ‘serverTimezone)
Offline loading of wkwebview and problems encountered
【内功心法】——函数栈帧的创建和销毁(C实现)
[slam] lvi-sam analysis - Overview
多线程进阶:synchronized底层原理,锁优化、锁升级的过程
YUV to uiimage
PC side bug record
[internal mental skill] - creation and destruction of function stack frame (C implementation)
MySQL date and time function, varchar and date are mutually converted
Share several methods of managing flag bits in C program
Interpretation of afnetworking4.0 request principle
PC端-bug记录
BeanUtils.copyProperties无法复制不同List集合问题解决 Lists.transform函数
2022 summer practice (PowerDesigner tutorial learning record) (first week)
分享几种管理C程序中标志位的方法
使用navicat或plsql导出csv格式,超过15位数字后面变成000(E+19)的问题
11. < tag dynamic programming and subsequence, subarray> lt.115. Different subsequences + Lt. 583. Deletion of two strings DBC
IDEA配置 service(Run Dashboard) 服务,多模块同时启动