FFmpeg计算图像的SSIM的原理

server/2024/9/25 3:36:27/

SSIM算法基于HVS更擅长从图像中提取结构信息的事实,并且利用结构相似度来计算图像的感知质量。
在Z. Wang等人的论文Multi-scale structural similarity for image quality assessment中也提到, S S I M SSIM SSIM算法要好于当时的其它的感知图像质量指标。
SSIM的计算公式:
在这里插入图片描述
SSIM计算中的图像分割
==在整幅图片的跨度上,图像亮度的均值和方差变化较为剧烈;并且图像上不同区块的失真程度也有可能不同;再者人眼睛每次只能聚焦于一处,更关注局部数据而非全局数据。==因此如上的 S S I M SSIM SSIM算法不能直接作用于一整副图像。
在论文Image quality assessment: From error visibility to structural similarity中,作者采用 11 × 11 11 \times 11 11×11的滑动窗口将整副图像分割为 N N N个patch,然后计算每一个patch的 S S I M SSIM SSIM,最后计算所有patch的 S S I M SSIM SSIM值的平均数( M e a n S S I M : M S S I M Mean \ \ SSIM:MSSIM Mean  SSIM:MSSIM)作为整副图像的 S S I M SSIM SSIM
为避免滑动窗口带来的块效应,在计算每个patch的均值 μ \mu μ和方差 σ 2 \sigma^2 σ2时,作者采用 σ = 1.5 \sigma=1.5 σ=1.5的高斯卷积核作加权平均。整副图像有 N N N个patch,则 M S S I M MSSIM MSSIM的计算公式为:
在这里插入图片描述
FFmpeg计算SSIM的实际实现

FFmpeg提供了计算 S S I M SSIM SSIM的实现:
https://github.com/FFmpeg/FFmpeg/blob/master/tests/tiny_ssim.c。
从代码注释中看到:为提升算法性能,没采用论文中的高斯加权方式计算每个patch的 S S I M SSIM SSIM,而采用了 8 × 8 8 \times 8 8×8的块来计算每个patch的 S S I M SSIM SSIM
在这里插入图片描述
standard approximation of overlapped 8x8 block sums

解释一下注释中的standard approximation of overlapped 8x8 block sums 的含义。分解成两个部分来解释:overlapped 8x8 block和sums。
overlapped 8x8 block的含义:
FFmpeg在计算图像 S S I M SSIM SSIM时,首先以 4 × 4 4 \times 4 4×4的块大小把图1所示的分辨率为 W × H W \times H W×H的图像:
在这里插入图片描述
图1:原始图像

在这里插入图片描述
图2:分割后的图像

对图2中的每一块用 b l o c k ( i , j ) block(i,j) block(i,j)来表示(图2中的红色块),FFmpeg使用 b l o c k ( i , j ) block(i,j) block(i,j)及其上、右、右上块(图2中的绿色块)来计算 S S I M : S S I M ( x i j , y i j ) SSIM:SSIM(x_{ij},y_{ij}) SSIM:SSIM(xij,yij)
b l o c k ( i , j ) block(i,j) block(i,j)及其上、右、右上块构成一个 8 × 8 8\times8 8×8的像素块,并且该 8 × 8 8\times8 8×8块和计算 b l o c k ( i , j + 1 ) block(i,j+1) block(i,j+1) S S I M SSIM SSIM用到的 8 × 8 8\times8 8×8的块存在重合像素,这就是注释中的overlapped 8x8 block的真正含义。
根据如上规则: i ∈ [ 1 , H 4 ] , j ∈ [ 0 , W 4 − 1 ] i \in [1,\frac{H}{4}],j \in [0,\frac{W}{4}-1] i[1,4H],j[0,4W1],即第0行和最后一列的块不会计算 S S I M SSIM SSIM。最后FFmpeg中的 S S I M SSIM SSIM公式为:
在这里插入图片描述
sums的含义

如前所述,分析了FFmpeg计算图像的 S S I M SSIM SSIM的整体思路,接下来分析FFmpeg是如何计算 b l o c k ( i , j ) block(i,j) block(i,j) S S I M ( x i j , y i j ) SSIM(x_{ij},y_{ij}) SSIM(xij,yij)的,即可解释sums的含义。
首先利用源码中的函数ssim_4x4x2_core()来计算 b l o c k ( i , j ) block(i,j) block(i,j)块的结构相似性指标,包含4个指标:
s1:参考图像在 b l o c k ( i , j ) block(i,j) block(i,j)块的像素之和
s2:受损图像在 b l o c k ( i , j ) block(i,j) block(i,j)块的像素之和
ss:参考图像和受损图像在 b l o c k ( i , j ) block(i,j) block(i,j)块的像素平方之和
s12:参考图像和受损图像在 b l o c k ( i , j ) block(i,j) block(i,j)块的对应像素乘积之和。
在这里插入图片描述
如上4个指标是后续会用到的sums(4类sum,称为sums),该sums也就是overlapped 8x8 block sums中的sums的概念。

利用sums计算各4x4块的SSIM
接下来利用该sums值计算 S S I M SSIM SSIM。为提升效率,FFmpeg会按照行来计算每一行的各个块的sums数据,并将每个行块的sums数据存储在长度为 W 4 \frac{W}{4} 4W的数组指针sum((int(*)[4]))中
sum指针有两种:

sum0:存储当前行的各块的sums结果
sum1:存储当前行的上一行的sums结果

先计算第 i − 1 i-1 i1行块和第 i i i行块的sums结果,并分别存入sum1和sum0中。然后遍历第 i i i行块的每一个块,并利用sum1和sum0中计算的结果来计算每一块的 S S I M SSIM SSIM
函数ssim_end4()展示了如何利用 b l o c k ( i − 1 , j ) block(i-1,j) block(i1,j) b l o c k ( i − 1 , j + 1 ) block(i-1,j+1) block(i1,j+1) b l o c k ( i , j ) block(i,j) block(i,j) b l o c k ( i , j + 1 ) block(i,j+1) block(i,j+1)的sums信息来计算 S S I M ( x i j , y i j ) SSIM(x_{ij},y_{ij}) SSIM(xij,yij)

  1. 先对4个块的sums结果进行加和处理,得到 8 × 8 8\times8 8×8块的sums结果
  2. 利用该 8 × 8 8\times8 8×8块的sums来计算 b l o c k ( i , j ) block(i,j) block(i,j) S S I M SSIM SSIM
    源码中ssim_end1()展示了如何利用 8 × 8 8\times8 8×8块的sums信息来计算 S S I M SSIM SSIM。具体的计算方法如下。
    将红色区块 b l o c k ( i , j ) block(i,j) block(i,j)的图像放大一点,如图3所示。我们接下来计算其 S S I M SSIM SSIM
    在这里插入图片描述
    图3: b l o c k ( i , j ) block(i,j) block(i,j)的示意图

在计算时,首先将4个区块的sums值求和,得到 8 × 8 8\times8 8×8区块的sums值,分别为:
在这里插入图片描述
利用如上的公式对 S S I M SSIM SSIM的公式进行计算可以得到:
在这里插入图片描述
FFmpeg源码中,对 C 1 C_1 C1 C 2 C_2 C2的定义中的因子64或63也是根据上面的公式,但是从公式看,FFmpeg对ssim_c1的计算少乘了64:
在这里插入图片描述
为简化计算,FFmpeg还做了如下的定义:

在这里插入图片描述
最终在FFmpeg中,计算 S S I M SSIM SSIM的公式为:
在这里插入图片描述
如上公式就是源码的函数ssim_end1()中最终的计算方式。

利用各块的SSIM计算图像的SSIM

计算完所有块的 S S I M SSIM SSIM之后,所有块的平均 S S I M SSIM SSIM作为该图像的 S S I M SSIM SSIM
在这里插入图片描述

编码过程中的技巧
FFmpeg计算 S S I M SSIM SSIM的实现中,为提升效率和抽象代码逻辑,利用很多的编程技巧,如:

  1. 计算YUV各分量图像宽度时用w >> !!i
  2. 为了避免对第0行的特殊处理,采用两层循环来处理
  3. 计算每一行的各块的sums信息时,为了降低循环次数,每次循环计算2个块的sums结果,ssim_4x4x2_core的函数名可能就是这么来的。
  4. 计算每一行的各块的 S S I M SSIM SSIM时,为了降低循环次数,每次循环计算4个块的 S S I M SSIM SSIM,源码中的ssim_end4的函数名可能就是这么来的。

http://www.ppmy.cn/server/31131.html

相关文章

【数学建模】2024五一数学建模C题完整论文代码更新

最新更新:2024五一数学建模C题 煤矿深部开采冲击地压危险预测:建立基于多域特征融合与时间序列分解的信号检测与区间识别模型完整论文已更新 2024五一数学建模题完整代码和成品论文获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/gyoz9ou5upv…

合并两个有序数组(详解)

合并两个有序数组(详解) 合并两个有序数组 题目: 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,…

无人机+三维建模:倾斜摄影技术详解

无人机倾斜摄影测量技术是一项高新技术,近年来在国际摄影测量领域得到了快速发展。这种技术通过从一个垂直和四个倾斜的五个不同视角同步采集影像,从而获取到丰富的建筑物顶面及侧视的高分辨率纹理。这种技术不仅能够真实地反映地物情况,还能…

一文读懂:到底什么是SCDN?

最近大家一定经常听到CDN这个词,对于之前没接触过这个行业的人,可能会听的云里雾里,不明所以。 那到底什么是SCDN呢? 简单理解:SCDN数据快递前置仓? SCDN,全称 Secure Content Delivery Networ…

k8s集群Grafana精选dashboard页面

文章目录 参考文档 Grafana自选模板推荐模板:13332、13824、14518Grafana默认配置我们选择 Node Exporter/Nodes 的 Dashboard 进去:点击 Kubernetes/Networking/Cluster 进去使用模板查看结果 Grafana接入Prometheus数据Grafana添加监控模板导入 1860_r…

pygame鼠标绘制

pygame鼠标绘制 Pygame鼠标绘制效果代码 Pygame Pygame是一个开源的Python库,专为电子游戏开发而设计。它建立在SDL(Simple DirectMedia Layer)的基础上,允许开发者使用Python这种高级语言来实时开发电子游戏,而无需被…

Qt简单离线音乐播放器

有上传本地音乐文件&#xff0c;播放&#xff0c;暂停&#xff0c;拖拉进度条等功能的播放器。 mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <QMediaPlayer> #include <QFileDialog> #include <QTime&g…

python学习笔记----面向对象(十)

一、什么是类 类是一个抽象的模板&#xff0c;用于创建具体的实例。可以将类理解为一个蓝图&#xff0c;它定义了一系列对象共有的属性&#xff08;数据&#xff09;和方法&#xff08;函数&#xff09;。类是对一组具有相同属性和功能的对象的抽象。例如&#xff0c;你可以定…