【FCon上海】与行业领袖共话AI大模型、数字化风控等前沿技术。 了解详情
写点什么

图片相似度计算:深入理解 DCT 变换以及感知哈希

  • 2018-11-21
  • 本文字数:3376 字

    阅读完需:约 11 分钟

图片相似度计算:深入理解DCT变换以及感知哈希

AI 大模型超全落地场景&金融应用实践,8 月 16 - 19 日 FCon x AICon 大会联诀来袭、干货翻倍!

缘起

Android 上硬件编解码一直是个老大难问题,就解码来说,硬解码本身并不困难,只要按照 MediaCodec 的流程开发即可。但由于系统碎片化,硬件规格不一致,硬件解码会到黑屏,花屏,绿屏之类的显示问题。为了不招致用户投诉,我们在做视频解码的时候不太敢开启硬件加速,一般会采用保守策略,即以软解为主,优先保证画面正常,但牺牲了性能。


一般解决这个问题的方案是使用黑(白)机型名单下发配置(如:腾讯视频),或者暴露开关让用户手动去控制是否走硬件解码(如:bilibili)。


使用机型黑(白)名单有一定的作用,但其问题也显而易见:


  • 需要浪费大量的人力,精力进行机型测试,去维护,发布名单

  • 覆盖度偏低,一般只覆盖 TOP 机型

  • 缺乏时效性,例如新机型上市不能及时跟进

  • 不一定准确,因为硬解是否成功,跟视频源也有很大关系,同一个机型可能解这个视频不成功,另外一个视频又是成功的。按照机型"一刀切"的前提是要保证视频规格一致,这样才最健壮。


通过开关让用户切换体验太差,尤其是“抖音”之类的短视频 App,总不能每个界面加个开关让用户去切换解码器这么深奥的东西吧,从用户角度讲,我为什么要关心这个什么解码器怎么设置,只要视频能正常看就行。


仔细思考一下,我们其实可以实现自动化的检测,即模拟人工检测流程,把样本视频各软硬解一遍,然后对比他们的解码结果(图片)就能够知道硬解码是否能跑通。解码的流程轻车熟路,那么这里的关键问题就是我们如何进行图片对比?如何量化图片的差异度?

图片检索技术

图片对比其实跟"以图搜图"本质上是同一种技术,通常有几种做法 MSE,均值哈希,色彩直方图以及 OpenCV 里面一些提取图像特征的高级算法,如 Sift,Surf 等。基于移动端的运行效率,安装包大小,以及需求本身考虑,我们放弃引入 OpenCV。MSE 属于逐像素对比,对像素值要求过于严格,太简单粗暴,色彩直方图不太好量化差异度。基于以上考虑,我们选择图像哈希算法,它可以输出汉明距离,方便量化软硬解结果的差异度。


哈希算法有三种,平均哈希,感知哈希和差异度哈希,基于准确度考虑,我们选择实现较复杂一些的感知哈希算法。另基于性能考虑,我们在 Android 平台上使用 C++实现算法,通过 JNI 接口给 Java 调用。Java 层输入 Android 的 Bitmap 对象,输出为图片指纹,再通过对比指纹的汉明距离,我们即可判断出来解码是否正常。


Java 层接口签名如下:


public native long getHash(Bitmap bitmap, int algorithm);public native long getHammingDistance(long hash1, long hash2);
复制代码


下面分析一下感知哈希实现的方法和背后的原理,使之知其然,知其所以然。

图片的构成


图一



图二


我们知道图片由 RGB 三原色构成这称之为加色法,我们可以认为图片有三个维度(暂不考虑 Alpha)。分析上面两幅图,图一为原图,可以发现图片里蕴含的大部分信息都是低频的,比如天空,绿叶,树枝等,他们很少变化。高频信息是小鸟的眼睛,嘴巴等细节。图二是把图一经过缩放且只保留亮度信息,可以看到这有效的移除了图片的细节,即高频信息,展示了图片的低频部分。图片的低频部分决定了图片的大体结构,高频部分则完善了图片的细节。我们在对比图片是否相似的时候,其实更关注的是中低频部分的差异度。


在实践中,我们可以把图片从 RGB 转换为 YCbCr 格式,只提取 Y 的部分参与计算,实现降维,以减少运算量。再把图片缩放到 32*32 大小,丢弃掉大部分高频信息。由于进行了降维和缩放,后续步骤我们的运算量已大大减少。


把图片从空域转换到频域,我们需要使用 DCT(二维离散余弦变换)。DCT 也是 JPEG 以及 H264 压缩算法的核心部分,感兴趣的可以继续深入了解视频压缩算法的相关研究。

感知哈希与 DCT(离散余弦变换)

为了让大家深入了解背后的原理,这里打算展开介绍一下 DCT,以及它为什么能检测出来图片的相似程度。本文恐怕是网络上能找到讲解 DCT 最详细的一篇文章了,如果你对背后的原理不感兴趣,也可以直接跳过。



从空域到频域


DCT 由如下的公式定义,N 和 M 为矩阵的行数和列数


\begin{equation}F(u, v) = \left (\frac{2}{N} \right )^{\frac{1}{2}} \left (\frac{2}{M} \right )^{\frac{1}{2}} C(u)C(v) \sum_{i=0}^{N-1}\sum_{j=0}^{M-1} f(i,j)cos\left [\frac{\left(2i+1\right)u\pi}{2N} \right ]cos\left [\frac{\left(2j+1\right)v\pi}{2N} \right ]\end{equation}



其中:


  • u,v = 离散频率变量(0,1,2…7)

  • f(i,j) = 图像在 i 行 j 列的像素值

  • F(u,v) = DCT 结果


我们先研究一个最简单的场景,假设图片像素值如下:



当 N 和 M 都为 2 时,上述公式可简化为:


\begin{equation}F(u,v) = C(u)C(v) \sum_{i=0}^{1}\sum_{j=0}^{1} f(i,j)cos\left [\frac{\left(2i+1\right)u\pi}{4} \right] cos\left [\frac{\left(2j+1\right)v\pi}{4} \right]\end{equation}


下面我们来计算二维 DCT



即,结果是:



用 Python 的相关模块可以交叉验证我们的计算结果:


>>> import numpy as np>>> from scipy.fftpack import dct>>> d=np.matrix([[1,3],[2,0]])>>> dct(dct(d,axis=0,norm="ortho"),axis=1,norm="ortho")array([[ 3.,  0.],       [ 1., -2.]])
复制代码


在实践上,上述方式的计算效率不高,更加简便的计算方式是使用 DCT 矩阵:



若 N 取 2,得到 DCT 矩阵



若 N 取 8,得到的矩阵是这样的



其中 i=0 时,即第 0 行,称为 DC 分量,i=1-7 成为 AC 分量,用图表形式表示如下



i=1



i=2



i=3



i=4



i=5



i=6



i=7


有这样一个矩阵的话,我们再进行 DCT 变换就非常简单了:



其中:


  • T = DCT 矩阵

  • M = 图像数据

  • D = DCT 结果


这是对一张 8*8 图片应用 DCT 变换得到的矩阵结果:



这个矩阵最左上角是低频信息,右下角是高频信息。有个神奇的东西叫基准样式。



信不信由你,任意一张 8*8 的图,都可以由标准图中的的小图以一定比例叠加而合成,而每个小图的权重,由 DCT 变换得到的矩阵决定,是不是很有意思。DCT 变换后左上角一般是比较大的数字,而右下角一般是比较小的数字,这暗含了图片中低频信息占的比重较多,因此我们在做图片或者视频编码压缩的时候,正是通过量化舍弃右下角的高频信息,来实现信息的压缩。

图片差异度

我们在对比图片差异的时候,正是通过对比频域信息来实现的。在我们的实现中,首先把软硬件解码后的图片转成 YCbCr 格式,只提取其中的 Y,实现降维,再把图片缩放到 32*32 大小,进一步减少运算量,同时舍弃了一部分高频信息。再应用 32*32 的 DCT 把图片转换到频域,从频域矩阵中提取 8*8 中低频区域的系数,计算算数平均值。



矩阵中的每个值再与 D 比较,大于 D 计 1,小于 D 计 0,按位存储,我们即可得到一个图片指纹。通过计算两个图片指纹的差异,我们就可以得到可以量化图片差异度的数字。


当差异为 0 时,我们认为两张图片完全一样,差异越大,表明图片越不相似。对于解码出现绿屏,花屏的情况,我们可以有效的检测出来。


绿屏案例,相似度 24:



花屏案例,相似度 20:



检测 Demo 截图:



2018-11-21 17:003517

评论 1 条评论

发布
暂无评论
发现更多内容

技术实践|大模型内容安全蓝军的道与术

百度安全

区块链交易所系统开发指南教程及功能

系统开发咨询1357O98O718

Swap交易所系统开发教程步骤及详细

系统开发咨询1357O98O718

把 KubeBlocks 跑在 Kata 上,真的可行吗?

小猿姐

数据库 云原生 Kata Containers

Redis的数据类型到底有什么奥秘

百度搜索:蓝易云

redis 云计算 Linux 运维 云服务器

架构实战营 - 模块二 - 作业

小畅

数据库安全策略有哪些?看YashanDB如何守护数据库安全(上篇)

Geek_2d6073

Uniswap丨justswap丨pancakeswap去中心化薄饼交易所系统开发指南详细及源码

系统开发咨询1357O98O718

短剧对接广告系统开发详细案例及源码

系统开发咨询1357O98O718

博睿数据亮相GOPS全球运维大会,Bonree ONE 2024春季正式版发布!

博睿数据

PPT时间轴是什么,该如何制作?分享2种常见绘制方法!

彭宏豪95

职场 PPT 在线白板 时间轴 效率软件

现货量化合约跟单项目系统开发稳定版及详细

系统开发咨询1357O98O718

还没用上 Llama3? 一条命令集成到你的应用!

Jade@pluto-lang

AWS SageMaker LLM #LangChain Llama3

鸿蒙HarmonyOS实战-ArkUI组件(Video)

蜀道山

鸿蒙 HarmonyOS 组件 鸿蒙开发 构架

鸿蒙HarmonyOS实战-ArkUI组件(Popup)

蜀道山

鸿蒙 HarmonyOS 组件 鸿蒙开发 PopupWindow

区块链交易所系统开发流程指南/案例详细/源码项目

系统开发咨询1357O98O718

DeFi/IDO/LP/DApp代币燃烧模式质押挖矿系统开发详细指南及流程

系统开发咨询1357O98O718

永续合约交易所跟单系统开发步骤详细/功能逻辑/源码程序

系统开发咨询1357O98O718

Solana土狗币也要做市刷量?PandaTool市值机器人使用教程

加密先生

Solana PandaTool

澳鹏中国大模型智能开发平台4大优势

澳鹏Appen

人工智能 数据 数据集 数据标注 大模型

MySQL 开源到商业(二):开源骇客沦为大厂社畜

小猿姐

MySQL 数据库

连获多项权威认证!YashanDB安全可靠能力“再加码”

Geek_2d6073

现货合约量化跟单交易所系统开发指南教程/需求设计/源码流程

系统开发咨询1357O98O718

智己汽车与火山引擎在模型应用及算法领域达成深度合作

新消费日报

以数智,赋医道:读懂医疗行业的智能化升级

脑极体

AI

YashanDB V23.2 LTS发版

Geek_2d6073

区块链DApp智能合约系统开发流程步骤及功能

系统开发咨询1357O98O718

DAPP去中心化智能合约系统开发功能详细及源码

系统开发咨询1357O98O718

数字货币交易所系统开发步骤详细及源码

系统开发咨询1357O98O718

DeFi/IDO/DAO/DApp/LP/Swap交易所兑换底池质押模式挖矿LP分红系统开发功能步骤及源码

系统开发咨询1357O98O718

UI自动化测试工程实践

智在碧得

自动化测试 UI自动化测试 UI自动化 技术实践 UI自动化例子

图片相似度计算:深入理解DCT变换以及感知哈希_移动_柳永峰_InfoQ精选文章