FFmpeg计算图像的SSIM的原理

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的函数名可能就是这么来的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/591805.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java-I/O-编写程序实现从文件中读取数据

定义一个类FileUtil,在FileUtil中定义一个方法 String readFromFile(File file),该方法从指定的文件中读取数据,并将读取到的数据以字符串的格式返回。 FileUtil类的接口定义: class FileUtil{ String readFromFile(File file){…

强大而简洁:初学Python必须掌握的14个单行代码

Python的魅力与单行代码的重要性 Python,作为一种高级编程语言,自诞生以来就以其简洁、易读、易学的特性而广受开发者喜爱。其魅力不仅在于其强大的功能和广泛的应用领域,更在于其能够用简洁的代码实现复杂的功能,这种能力在很大…

nodejs实战——搭建websocket服务器

本博客主要介绍websocket服务器库安装,并举了一个简单服务器例子。 服务器端使用websocket需要安装nodejs websocket。 cd 工程目录 # 此刻我们需要执行命令: sudo npm init上述命令创建package.json文件,系统会提示相关配置。 我们也可以使…

matlab绘制时间序列图,横坐标轴如何标注为月-日

Excel表格中有类似于如下 年月日对应的数据 导入 matlab中,为数值矩阵;了解该表格中的时间跨度为从2021年1月2日至2021年12月31日,中间没有缺失,绘图代码: % clear; timespan1[20210102 20211231]; datenn1datenum(da…

Visual studio调试技巧

Visual studio调试技巧 bug是什么?Debug和ReleaseDebugRelease 如何调试VS调试快捷键调试过程中查看程序信息查看临时变量的值查看内存信息查看调用堆栈查看汇编信息查看寄存器信息 编译常见错误编译型错误链接型错误运行时错误 bug是什么? bug的英文释…

用例设计规范示例

一个好的用例设计,可以让任何一个执行测试的测试人员都能够容易理解,好操作、易执行、无歧义。这就需要有一个用例设计规范。 下面是一组用例设计规范的示例。 用例编号命名规范化 用例具有规范的、统一的、唯一的标识,有助于实现对用例的…

VMware | 虚拟机开启摄像头

VMware | 虚拟机开启摄像头 打开主机摄像头功能 首先请确保主机摄像头打开。 若图像显示正常则可以。 确保主机虚拟机USB服务开启 进入系统服务界面,确保 VMware USB … 处于开启状态,如果没开启,将它打开。 开启虚拟机摄像头 在 V…

以信息挖掘为关键技术的智慧校园建设

随着信息技术的快速发展,数据信息资源以井喷的姿态涌现。数据信息的大量涌现给人们带来丰富的数据信息资源,但面对海量的信息资源时,加大了人们对有效信息资源获取的难度,数据挖掘技术正是这一背景下的产物,基于数据挖…

C语言/数据结构——每日一题(分割链表)

一.前言 今天在LeetCode觉得很不错,想和大家们一起分享这道链表题——分割链表:https://leetcode.cn/problems/partition-list-lcci废话不多说,让我们直接进入正题吧。 二.正文 1.1题目描述 1.2题目分析 大致思路:我们可以通过…

手撸Mybatis(二)—— 配置项的获取

本专栏的源码:https://gitee.com/dhi-chen-xiaoyang/yang-mybatis。 配置项解析 在mybatis中,一般我们会定义一个mapper-config.xml文件,来配置数据库连接的相关信息,以及我们的mapperxml文件存放目录。在本章,我们会…

【C++】---模板进阶

【C】---模板进阶 一、模版参数1、类型参数2、非类型参数 二、模板的特化1、函数模板的特化2、类模板特化(1)全特化(2)偏特化 三、模板分离编译1、模板支持分离编译吗?2、为什么模板不支持分离编译?3、如何…

《21天学通C++》(第十五章)标准模板库简介

本章简单介绍STL容器、迭代器和算法的基本概念,之后几章会分别详述 1.STL容器 STL容器是STL中用于存储集合数据的组件,它们可以被看作是模板类,允许开发者定义特定类型的容器发,这里按照C11标准分为四类:顺序容器、关…

Vmware虚拟机瘦身及Samba服务不可用问题解决

虚拟机磁盘空间膨胀是一个令人头疼的问题,特别是对许多搞开发的小伙伴。无论是做后台服务、嵌入式还是Android开发,都面临着这个难题。首先,操作系统本身就已占用不少空间,更新安装包,再下载一些开源软件,剩…

leetcode_47.全排列 II

47. 全排列 II 题目描述:给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 示例 1: 输入:nums [1,1,2] 输出: [[1,1,2],[1,2,1],[2,1,1]]示例 2: 输入:nums [1,2,3] …

Server 2022 IIS10 PHP 7.2.33 升级至 PHP 8.3 (8.3.6)

下载最新版本 PHP 8.3 (8.3.6),因为是 FastCGI 执行方式,选择 Non Thread Safe(非线程安全)。 若有以下提示: The mysqli extension is missing. Please check your PHP configuration. 或者 PHP Fatal error: Uncaught Error: Class &qu…

41 POSIX信号量

POSIX信号量 POSIX信号量和System V信号量作用相同,都是用于同步操作,达到无冲突的访问共享资源目的,但POSIX可以用于线程同步 31节说了信号量,信号量的本质是一个计数器。将共享资源从一个整体划分为很多不部分,就和…

可视化大屏应用场景:智慧安防,保驾护航

hello,我是大千UI工场,本篇分享智慧安防的大屏设计,关注我们,学习N多UI干货,有设计需求,我们也可以接单。 实时监控与预警 可视化大屏可以将安防系统中的监控画面、报警信息、传感器数据等实时展示在大屏上…

【word技巧】Word目录如何设置为对齐?

Word文档的目录有些在修改之后无法对齐,大家是不是会自己手动删除省略号?今天分享一个方法,设置之后,tab一键对齐目录。 先选中目录,然后点击段落设置界面,选择左下角的【制表位】 然后将制表位置设置为【…

蓝桥杯练习系统(算法训练)ALGO-947 贫穷的城市

资源限制 内存限制:256.0MB C/C时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 问题描述 某城市有n个小镇,编号是1~n。由于贫穷和缺乏城市规划的人才,每个小镇有且仅有一段单向的公路通往别…

一机游领航旅游智慧化浪潮:借助前沿智能设备,革新旅游服务效率,构建高效便捷、生态友好的旅游服务新纪元,开启智慧旅游新时代

目录 一、引言 二、一机游的定义与特点 (一)一机游的定义 (二)一机游的特点 三、智能设备在旅游服务中的应用 (一)旅游前的信息查询与预订支付 (二)旅游中的导航导览与互动体…