图像哈希4:基于四元数 SVD 的奇异值的鲁棒图像哈希
图像哈希系列:
图像哈希1:基于四元数离散傅里叶变换和对数极坐标的鲁棒图像哈希算法
图像哈希2:基于环形分区和NMF的鲁棒感知图像哈希(CCF A)
图像哈希3:基于四元数离散余弦变换的鲁棒感知图像哈希研究(性能优于近年一些较好的研究)
图像哈希4:基于四元数 SVD 的奇异值的鲁棒图像哈希
未完待续…
欢迎交流
图像哈希4:基于四元数 SVD 的奇异值的鲁棒图像哈希
论文1:Robust Image Hashing With Singular Values Of Quaternion SVD,论文地址
doi:https://doi.org/10.1093/comjnl/bxz127
摘要:图像哈希是许多多媒体系统的有效技术,如图像检索、图像认证和图像复制检测。鲁棒性和区分度之间的分类是图像哈希最重要的性能之一。该论文提出了一种使用四元奇异值分解(QSVD)奇异值的鲁棒图像哈希方法。主要贡献在于创新性地使用了 QSVD,它可以从 CIE L∗a∗b∗ 色彩空间中提取稳定且具有区分度的图像特征。此外,块的图像特征被视为直角坐标中的一个点,并通过计算其点与参考点之间的欧氏距离进行压缩。由于欧氏距离比原始图像块特征所需的存储空间更小,因此这种技术有助于制作具有辨别力且紧凑的哈希值。结果表明,该论文的图像哈希算法可以抵御多种数字运算,并达到良好的判别效果。ROC曲线比较表明,该论文的图像哈希在分类性能上优于当年一些最先进的算法。
关键词:图像哈希;四元数矩阵;四元数奇异值分解(QSVD);颜色空间;图像特征
介绍
图像哈希是许多多媒体系统的有效技术,如图像检索、图像取证、图像认证、图像复制检测、图像水印和图像质量评估等。目前,许多图像哈希算法在鲁棒性和区分度之间难以达到良好的分级,尤其是在处理彩色图像时。四元数是一种有用的数学理论,已被广泛应用于处理彩色图像,如彩色图像去噪、彩色图像配准和彩色图像水印等。然而,如何利用四元数来提高彩色图像哈希的效率还没有得到很好的研究。该论文中,利用四元数奇异值分解(QSVD)开发了一种新型的鲁棒图像哈希算法,它能在鲁棒性和辨识度之间做出很好的权衡。与现有的图像哈希算法相比,该论文的算法主要有以下贡献: (1) 提出通过 QSVD 从 CIE L∗a∗b∗ 色彩空间提取鲁棒图像特征。该论文选择图像块的奇异值作为图像特征。由于奇异值包含了图像块的大部分信息,因此提取的图像特征具有很强的区分度。此外,CIE L∗a∗b∗ 色彩空间在感知上是统一的。因此,从感知色彩空间提取的图像特征比在其他色彩空间计算的特征更稳定。(2) 将图块的图像特征视为直角坐标中的一个点,并通过计算其点与参考点之间的欧氏距离来压缩图块特征。最后,通过连接所有欧氏距离形成图像哈希值。由于欧氏距离比原始图像特征所需的存储空间更小,因此这种技术有助于生成具有辨别力且紧凑的图像哈希值。
相关工作
图像哈希是一种对输入图像进行紧凑表示的技术。它根据图像的视觉内容,将视觉上相同的图像映射为相同或相似的哈希值。图像哈希的第一个特性被称为鲁棒性。这一特性的要求是,图像哈希应该对正常的数字操作(如 JPEG 压缩和图像增强)具有鲁棒性。这是因为经过这些数字操作后,处理后的图像仍与原始版本相似,但其数字表示却大不相同。图像哈希的第二个特性被称为辨别力。它要求图像哈希对不同的图像产生不同的哈希值。这一特性至关重要,因为在实际应用中,不同图像的数量远远大于相似图像的数量。在过去几年中,研究人员在图像哈希方面取得了很大进展,并设计了许多算法来提高鲁棒性和区分度的性能。这些算法可分为以下四类。
(1) 基于正交变换的算法。常用的正交变换包括离散傅里叶变换(DFT)、离散余弦变换(DCT)、离散小波变换(DWT)和四元极余弦变换(QPCT)。例如,Swaminathan 等人提出利用极坐标中的 DFT 特征计算图像哈希。这种哈希算法可抵御适度的几何变换和图像滤波。Qin 等人利用 DFT 和非均匀采样提取图像哈希值。这种方案可以抵御小角度旋转。最近,Laradji 等人提出用四元傅里叶变换(QFT)计算哈希值。QFT 哈希提高了判别能力,但其鲁棒性仍然不够好。欧阳等人利用四元数傅里叶变换和对数极性变换(LPT)来构建用于身份验证的图像哈希值。这种方法具有良好的鲁棒性,尤其是大角度旋转时。在另一项研究中,Fridrich 和 Goljan根据 DCT 系数可指示视觉图像内容的特性,提出了一种用于数字水印的鲁棒哈希方法。Tang 等人利用优势 DCT 系数构建了用于复制检测的鲁棒哈希。这两种哈希方法对图像旋转都很敏感。Wang 等人利用 Watson 基于 DCT 的视觉模型开发了用于内容验证的图像散哈希。这种方法对图像模糊和图像噪声具有良好的鲁棒性。在另一项研究中,Venkatesan 等人利用 DWT 统计来构建哈希值。这种算法对对比度调整很脆弱。Monga 和 Evans利用一种称为末端停止小波变换的 DWT 来寻找视觉点以构建哈希值。这种哈希算法可以抵御 JPEG 压缩和小角度旋转。Ahmed 等人利用 DWT 和安全哈希算法设计了一种用于身份验证的哈希方案。这种哈希算法对亮度和对比度的调整很敏感。Tang 等人提取了每个像素的颜色矢量角(CVA),计算了 CVA 的块平均值,并通过二维 DWT 压缩了块平均矩阵。这种哈希算法可以抵御小角度旋转。最近,Li 等人通过 QPCT 提取旋转不变特征来构建哈希值。这种方法速度很快。
(2) 基于投影变换的算法。著名的投影变换有 Radon 变换及其称为扇形梁变换(FBT)的变体。Lefebvre 等人的早期工作是基于 RT 投影中点的哈希算法。他们的哈希算法可以抵御几何变换,但辨别能力不强。Wu 等人联合使用 RT、DWT 和 DFT 建立了一种鲁棒哈希,用于抵御打印扫描的攻击。在另一项研究中,Lei 等人在 RT 域计算矩特征,并使用矩的 DFT 系数生成哈希值。这种方法可抵御大角度旋转。由于 RT 的计算成本较高,上述算法都比较耗时。在另一项研究中,利用名为 FBT 的 RT 变体提取哈希值。与基于 RT 的哈希算法相比,基于 FBT 的哈希算法在运行速度和分类方面都有更好的表现。
(3) 基于统计特征的算法:图像哈希中广泛使用的统计特征是直方图。例如,Schneider 和 Chang利用块直方图建立图像哈希。这种哈希算法对 JPEG 压缩很稳定,但对大角度旋转很敏感。Xiang等人利用直方图的不变性建立了鲁棒哈希。这种方案可以抵御几何变换。最近,Vadlamudi 等人计算了块直方图,将直方图分区分布到大型容器中,并利用两个相邻容器之间像素数量的比值来形成哈希值。这种哈希算法对正常的数字操作具有鲁棒性。Tang 等人从输入图像中提取 CVA,并用 DCT 压缩 CVA 直方图,从而生成图像哈希值。这种方法可以抵御大角度旋转。第二个用于图像哈希的著名统计特征是矩。Tang 等人利用两种颜色空间中的不变矩得出了图像哈希值。Zhao 等人提出了基于 Zernike 矩和突出区域统计计算哈希值的方法。基于矩的哈希算法一般对几何变换具有鲁棒性,但其辨别能力有待提高。在另一项研究中,欧阳等人利用四元数 Zernike 矩设计了用于图像认证的哈希算法。该方案可以承受高斯噪声、椒盐噪声和图像滤波,但对亮度调整和伽玛校正比较脆弱。最近,Hosny 等人利用四元极复指数变换的矩来构建哈希值。除了直方图和矩外,其他统计特征也有报道。例如,Tang 等人提出从 HSI 和 YCbCr 色彩空间中提取图像块的局部统计特征。在另一项研究中,Tang 等人计算了图像环的感知统计特征,并利用特征向量距离构建哈希值。Qin等人联合使用奇异值分解(SVD)、CVA和Canny算子计算基于圆的方差和基于块的方差,并对其进行量化和加扰,从而得到安全的哈希值。该算法具有良好的感知鲁棒性,但运行速度有待提高。Tang 等人计算了输入图像的显著性图,将 DWT 应用于显著性图,并利用同心圆上 DWT 系数的统计特征来构建图像哈希。该方案在分类性能上优于哈希算法。
(4) 基于降维的算法。Kozat 等人的早期降维工作是使用 SVD。他们使用双 SVD 计算哈希值来提高旋转鲁棒性,但其代价是辨别性能下降。受和四元数理论的启发,Ghouti提出了一种与类似的图像哈希方法,即用 QSVD 代替 SVD。与哈希方法相比,基于 QSVD 的哈希方法显示出更好的分类性能,但性能还不够好。在另一项研究中,Davarzani 等人联合利用 SVD 和中心对称局部二进制模式来计算哈希值。这种算法可以抵御 JPEG 压缩和模糊,但其辨别能力有待提高。非负矩阵因式分解(NMF)也被用于图像哈希。例如,Tang 等人在词典框架下利用 NMF 和 DCT 设计了一种新的哈希算法。这种哈希算法具有良好的安全性,但对旋转比较敏感。在另一项研究中,Tang 等人构建了一个旋转不变的二次图像,并通过 NMF 从二次图像中学习了一个紧凑的哈希算法。其他有用的降维技术也有报道,如局部线性嵌入(LLE)和多维缩放(MDS)。例如,Sun 等人首次将 LLE 应用于图像哈希设计,并提出利用 LLE 权重矩阵中的关系来形成图像哈希。这种哈希方案可以抵御 JPEG 压缩,但对图像旋转很敏感。Tang 等人利用 MDS 得出了图像哈希值。在该方案中,颜色信息未被考虑,因此辨别能力的提高有限。
除了上述算法,还研究了其他技术。例如,利用压缩传感提取图像哈希值。文献[54]利用虚拟水印的检测理论设计了高效的图像哈希算法。哈里斯检测器和尺度不变特征变换结合起来构建哈希值。在 [56] 中,Gabor 滤波和晶格矢量量化被联合用于提取哈希值。文献 [57] 利用自适应和局部特征提取技术设计了多尺度哈希算法。文献[59]选择了块截断编码[58]来计算图像哈希值。在 [60] 中,利用稀疏编码得出鲁棒哈希。文献[61]选择在之字形块上随机行走来建立安全哈希算法。文献[62]利用显著结构检测和双交叉模式编码来计算哈希值。[61-62]中报告的两种算法都达到了很好的安全性,但它们的分类还不理想。
鲁棒性和鉴别力的分类是图像哈希算法最重要的性能之一,但现有的大多数算法在处理彩色图像时并没有达到很好的性能。针对这一问题,该论文提出了一种基于 QSVD 的新型鲁棒图像哈希算法。所提出的哈希算法通过 QSVD 从 CIE L∗a∗b∗ 色彩空间提取鲁棒图像特征,并通过计算欧氏距离压缩图像特征。实验结果表明,所提出的算法在鲁棒性和区分度之间的分类性能上优于当年一些最先进的算法。
提出的图像哈希算法
提出的图像哈希算法分为三个步骤。下图展示了提出的图像哈希算法的框图。第一步,通过一些数字运算对输入图像进行预处理,生成归一化图像。第二步,将归一化图像划分为非重叠块,并通过 QSVD 从感知色彩空间提取局部块特征。最后,通过计算特征之间的欧氏距离,对局部块特征进行压缩,生成简短的哈希值。这些步骤的详细说明如下。
预处理
在预处理过程中,该论文利用三种数字运算来减轻常用的内容保护运算对输入图像的影响。首先,利用双线性插值法将输入图像转换成标准尺寸 M × M。然后,利用 3 × 3 卷积掩码对调整后的图像进行高斯低通滤波。这一操作是为了减少图像噪声的影响。然后,将滤波后的彩色图像转换为感知色彩空间,即 CIE L∗a∗b∗ 空间,其中像素的色彩亮度用 L∗ 表示,像素的色度坐标分别用 a∗ 和 b∗ 表示。一般来说,从 RGB 空间到 CIE L∗a∗b∗ 空间的映射是通过 CIE XYZ 空间进行的。假设 R 是像素的红色分量,G 是绿色分量,B 是蓝色分量。
在此,将彩色图像转换到感知统一空间,因为感知空间中的 L∗ 颜色分量与人类感知的亮度相匹配,而且从感知空间提取的哈希值比用其他颜色空间计算的哈希值显示出更好的分类性能。下图为对预处理之后的lenna图像转化为CIE L∗a∗b∗ 空间。
通过QSVD进行局部特征提取
在这里先回顾一下四元数的基础知识。
四元数是复数的泛化,有四个部分:一个实部和三个虚部,可以写成:
q
=
a
+
b
i
+
c
j
+
d
k
q=a+bi+cj+dk
q=a+bi+cj+dk
其中 a , b , c 和 d 是实数,i, j 和 k 是服从以下规则的虚部:
i
2
=
j
2
=
k
2
=
−
1
,
i
j
=
−
j
i
=
k
,
j
k
=
−
k
j
=
i
,
k
i
=
−
i
k
=
j
i^2=j^2=k^2=-1,ij=-ji=k,jk=-kj=i,ki=-ik=j
i2=j2=k2=−1,ij=−ji=k,jk=−kj=i,ki=−ik=j
四元数的乘法规则不是交换式的。四元数 q 的共轭和模数分别定义如下:
q
‾
=
a
−
b
i
−
c
j
−
d
k
,
∣
q
∣
=
a
2
+
b
2
+
c
2
+
d
2
.
\overline q=a-bi-cj-dk,\left|q\right|=\sqrt{a^2+b^2+c^2+d^2}.
q=a−bi−cj−dk,∣q∣=a2+b2+c2+d2.
具有零实部的四元数 q 称为纯四元数。空间位置(x, y)上彩色图像f的一个像素有三个分量,可以表示为纯四元数:
f
(
x
,
y
)
=
f
R
(
x
,
y
)
i
+
f
G
(
x
,
y
)
j
+
f
B
(
x
,
y
)
k
,
f(x,y)=f_R(x,y)i+f_G(x,y)j+f_B(x,y)k,
f(x,y)=fR(x,y)i+fG(x,y)j+fB(x,y)k,
f
R
(
x
,
y
)
,
f
G
(
x
,
y
)
,
f
B
(
x
,
y
)
f_R(x,y),f_G(x,y),f_B(x,y)
fR(x,y),fG(x,y),fB(x,y)分别是
f
(
x
,
y
)
f(x,y)
f(x,y)的RGB分量值。
在本文中,利用 CIE L∗a∗b∗ 颜色空间的颜色分量来代替 RGB 颜色空间的颜色分量。换句话说,使用 L∗ 组件、a∗ 组件和 b∗ 组件来替换 f R ( x , y ) , f G ( x , y ) , f B ( x , y ) f_R(x,y),f_G(x,y),f_B(x,y) fR(x,y),fG(x,y),fB(x,y)。这里选择CIE L * a * b *颜色空间作为颜色空间是基于CIE L∗a∗b∗颜色空间在感知上是均匀的,从感知颜色空间中提取的图像特征比其他颜色空间中计算的图像特征更稳定。
由于彩色图像可以用纯四元数矩阵表示,因此我们可以利用 QSVD 从纯四元数矩阵推导出鲁棒哈希值。假设
A
∈
H
M
×
M
A\in H^{M×M}
A∈HM×M 是一个秩为 r 的四元数矩阵:
A
=
U
(
∑
r
0
0
0
)
V
△
A=U\begin{pmatrix} \sum_r& 0\\ 0&0 \end{pmatrix} V^\bigtriangleup
A=U(∑r000)V△
其中,
U
∈
H
M
×
M
U\in H^{M×M}
U∈HM×M 和
V
∈
H
M
×
M
V\in H^{M×M}
V∈HM×M 是四元数单元矩阵,分别包含 A 的左奇异向量和右奇异向量;
△
\bigtriangleup
△是四元数转置-共轭算子;
∑
r
\sum_r
∑r是实数对角矩阵,其非零项为 A 的奇异值。QSVD 的高效算法总结如下: (i) 计算四元数矩阵的等效复数矩阵;(ii) 用复数矩阵的常规 SVD 方法对等效复数矩阵进行 SVD;(iii) 由于四元数矩阵的奇异值在等效复数矩阵的 SVD 结果中出现两次,可通过删除重复元素提取奇异值;(iv) 利用等效复数矩阵的单元矩阵计算四元数矩阵的四元数单元矩阵。有关该算法的更多详情,请参阅文献。
为了通过 QSVD 提取局部特征,论文将预处理图像的四元数矩阵划分为 m × m 大小的非重叠块。为简单起见,令 M 为 m 的整数倍。因此,总共有
N
=
(
M
/
m
)
2
N = (M/m)^2
N=(M/m)2 个块。假设
B
i
(
q
)
B^{(q)}_i
Bi(q)(1 ≤ i ≤ N)是四元数矩阵的第 i 个块,索引顺序为从上到下、从左到右。我们对每个块
B
i
(
q
)
B^{(q)}_i
Bi(q)应用 QSVD。
B
i
(
q
)
B^{(q)}_i
Bi(q)的 QSVD 公式定义如下:
B
i
(
q
)
=
U
i
(
q
)
S
i
(
V
i
(
q
)
)
Δ
\mathbf{B}_{i}^{(q)}=\mathbf{U}_{i}^{(q)} \mathbf{S}_{i}\left(\mathbf{V}_{i}^{(q)}\right)^{\Delta}
Bi(q)=Ui(q)Si(Vi(q))Δ
其中
U
i
(
q
)
U^{(q)}_i
Ui(q) 和
V
i
(
q
)
V^{(q)}_i
Vi(q) 是
B
i
(
q
)
B^{(q)}_i
Bi(q) 的左右奇异向量,
S
i
=
d
i
a
g
(
σ
i
,
1
,
σ
i
,
2
,
.
.
.
,
σ
i
,
m
)
S_i = diag(σ_{i,1} , σ_{i,2}, ... , σ_{i,m})
Si=diag(σi,1,σi,2,...,σi,m)是由奇异值组成的实数对角矩阵,其中
σ
i
,
1
≥
σ
i
,
2
≥
.
.
.
≥
σ
i
,
m
σ_{i,1} ≥ σ_{i,2} ≥ ... ≥ σ_{i,m}
σi,1≥σi,2≥...≥σi,m。本文选择
B
i
(
q
)
B^{(q)}_i
Bi(q) 的第一奇异值和第二奇异值作为块特征,分别用
p
i
(
1
)
=
S
i
(
1
,
1
)
=
σ
i
,
1
p^{(1)}_i = S_i(1, 1) = σ_{i,1}
pi(1)=Si(1,1)=σi,1 和
p
i
(
2
)
=
S
i
(
2
,
2
)
=
σ
i
,
2
p^{(2)}_i = S_i(2, 2) = σ_{i,2}
pi(2)=Si(2,2)=σi,2 表示。在此,我们选择第一奇异值和第二奇异值作为特征。这是考虑到幅度较大的奇异值代表了图像中最多的信息。
接下来,我们分别将所有块的第一奇异值和第二奇异值连接起来,然后得到两个向量 p(1) 和 p(2),如下所示:
p
(
1
)
=
[
p
1
(
1
)
,
p
2
(
1
)
,
.
.
.
,
p
N
(
1
)
]
p
(
2
)
=
[
p
1
(
2
)
,
p
2
(
2
)
,
.
.
.
,
p
N
(
2
)
]
p^{(1)}=\left [ p_1^{(1)},p_2^{(1)},...,p_N^{(1)} \right ] \\ p^{(2)}=\left [ p_1^{(2)},p_2^{(2)},...,p_N^{(2)} \right ]
p(1)=[p1(1),p2(1),...,pN(1)]p(2)=[p1(2),p2(2),...,pN(2)]
这两个向量就是输入图像的局部特征。显然,这些特征的总数为 2N。需要注意的是,在图像哈希中使用的 QSVD 与 [47] 不同。具体来说,Ghouti [47] 使用 RGB 色彩空间构建输入图像的四元数矩阵,而该论文的图像哈希利用 CIE L∗a∗b∗ 色彩空间形成四元数矩阵。此外,Ghouti [47] 选择奇异向量作为图像特征,而该论文的图像哈希使用奇异值来生成图像特征。实验比较表明,该论文的图像哈希算法比 Ghouti [47] 提出的哈希算法具有更好的分类性能。
特征压缩
由于每个区块都会提取两个特征,该论文将区块特征视为直角坐标中的一个点,即
(
p
i
(
1
)
,
p
i
(
2
)
)
(p^{(1)}_i ,p^{(2)}_i )
(pi(1),pi(2)),并通过计算其点与参考点之间的欧氏距离来压缩区块特征。为此,首先要对数据进行如下归一化处理。
x
i
=
P
i
(
1
)
−
μ
p
(
1
)
δ
p
(
1
)
y
i
=
P
i
(
2
)
−
μ
p
(
2
)
δ
p
(
2
)
x_i=\frac{P_i^{(1)}-\mu_{p^{(1)}}}{\delta_{p^{(1)}} } \\ y_i=\frac{P_i^{(2)}-\mu_{p^{(2)}}}{\delta_{p^{(2)}} }
xi=δp(1)Pi(1)−μp(1)yi=δp(2)Pi(2)−μp(2)
其中,
μ
p
(
1
)
\mu_{p^{(1)}}
μp(1)和
μ
p
(
2
)
\mu_{p^{(2)}}
μp(2) 分别是
p
(
1
)
p^{(1)}
p(1) 和
p
(
2
)
p^{(2)}
p(2) 的均值,
δ
p
(
1
)
{\delta_{p^{(1)}}}
δp(1)和
δ
p
(
2
)
{\delta_{p^{(2)}}}
δp(2) 分别是 p(1) 和 p(2) 的标准差。它们的定义如下
μ
p
(
1
)
=
1
N
∑
i
=
1
N
p
i
(
1
)
μ
p
(
2
)
=
1
N
∑
i
=
1
N
p
i
(
2
)
\mu _{p^{(1)}}=\frac{1}{N} \sum_{i=1}^{N} p_i^{(1)} \\ \mu _{p^{(2)}}=\frac{1}{N} \sum_{i=1}^{N} p_i^{(2)} \\
μp(1)=N1i=1∑Npi(1)μp(2)=N1i=1∑Npi(2)
为了计算欧氏距离,需要生成一个参考点
(
x
μ
,
y
μ
)
(x_μ,y_μ)
(xμ,yμ),其中 xμ 和 yμ 是 x 和 y 的均值,定义如下:
x
μ
=
1
N
∑
i
=
1
N
x
i
y
μ
=
1
N
∑
i
=
1
N
y
i
x_{\mu}=\frac{1}{N} \sum_{i=1}^{N} x_i \\ y_{\mu}=\frac{1}{N} \sum_{i=1}^{N} y_i
xμ=N1i=1∑Nxiyμ=N1i=1∑Nyi
接下来,第 i 个块
(
x
i
,
y
i
)
(x_i, y_i)
(xi,yi)和参考点
(
x
μ
,
y
μ
)
(x_μ, y_μ)
(xμ,yμ)点之间的欧几里得距离由下式确定。
d
i
=
(
x
i
−
x
μ
)
2
+
(
y
i
−
y
μ
)
2
d_i=\sqrt{(x_i-x_{\mu})^2+(y_i-y_{\mu })^2}
di=(xi−xμ)2+(yi−yμ)2
由于 di 是一个浮点数,它被进一步量化为整数,用于通过以下方程减少存储。
h
(
i
)
=
[
d
i
×
100
+
0.5
]
h(i)=\left [ d_i\times 100+0.5 \right ]
h(i)=[di×100+0.5]
其中[·]是四舍五入运算。最后,我们将这些整数连接起来,就能得到图像哈希值:
h
=
[
h
(
1
)
,
h
(
2
)
,
.
.
.
,
h
(
N
)
]
h = [h(1), h(2), . . . , h(N)]
h=[h(1),h(2),...,h(N)]
因此,算法的长度为 N 个整数。在实验中,发现图像哈希元素可以用 10 位表示,因此我们的哈希长度为 10N 位。
哈希相似度评价
由于得到的图像哈希是一个整数表示,两个图像哈希的相似性可以通过L2范数来衡量。令
h
1
=
[
h
1
(
1
)
,
h
1
(
2
)
,
…
,
h
1
(
N
)
]
h_1 = [h_1 (1),h_1(2),…,h_1(N)]
h1=[h1(1),h1(2),…,h1(N)]和
h
2
=
[
h
2
(
1
)
,
h
2
(
2
)
,
…
]
,
h
2
(
N
)
]
h2 = [h2 (1), h2(2),…], h2 (N)]
h2=[h2(1),h2(2),…],h2(N)]表示两幅图像的哈希值。因此,它们的L2范数由下式确定:
d
(
h
1
,
h
2
)
=
∑
i
=
1
N
[
h
1
(
l
)
−
h
2
(
l
)
]
2
d(h_1,h_2)=\sqrt{\sum_{i=1}^{N} \left [ h_1(l)-h_2(l) \right ]^2 }
d(h1,h2)=i=1∑N[h1(l)−h2(l)]2
其中
h
1
(
l
)
h_1^{(l)}
h1(l) 和
h
2
(
l
)
h_2^{(l)}
h2(l) 分别是 h1 和 h2 的第
l
l
l 个元素。通常,较小的 L2 范数意味着更相似的输入哈希图像。如果 L2 范数大于阈值 T,输入哈希的图像被认为是不同的图像。否则,它们是视觉上相似的图像。
值:
h
(
i
)
=
{
0
,
d
i
<
T
1
,
d
i
≥
T
h(i)=\left\{\begin{matrix}0, d_i<T \\1,d_i\ge T \end{matrix}\right.
h(i)={0,di<T1,di≥T
其中T为序列
d
1
,
d
2
,
…
,
d
N
{d_1,d_2,…,d_N}
d1,d2,…,dN的排序结果的中间值。因此,图像哈希序列被定义为h = [h(1),h(2),…,h(N)]。
相似性度量
利用汉明距离来度量两个图像哈希之间的相似性。让
h
1
=
[
h
1
(
1
)
,
h
1
(
2
)
,
.
.
.
,
h
1
(
N
)
)
和
h
2
=
(
h
2
(
1
)
,
h
2
(
2
)
,
.
.
.
,
h
2
(
N
)
)
h1 = [h_1 (1), h_1 (2 ), . . ., h_1 (N))和h_2 = (h_2 (1), h_2 (2 ), . . ., h_2 (N))
h1=[h1(1),h1(2),...,h1(N))和h2=(h2(1),h2(2),...,h2(N))是两个图像哈希。那么,汉明距离可由下式计算:
d
(
h
1
,
h
2
)
=
∑
i
=
1
N
∣
h
1
(
1
)
−
h
2
(
i
)
∣
d(h_1,h_2)=\sum_{i=1}^{N} \left | h_1(1)-h_2(i) \right |
d(h1,h2)=i=1∑N∣h1(1)−h2(i)∣
其中 N 是图像哈希的长度,
h
1
(
i
)
h_1 (i)
h1(i) 和
h
2
(
i
)
h_2 (i)
h2(i) 分别是
h
1
h_1
h1 和
h
2
h_2
h2 的第 i 个元素。如果汉明距离大于阈值,则输入哈希的图像被视为内容不同的图像。否则,它们是视觉上相同的图像。
实验结果
在实验中,我们算法的使用参数如下:输入图像被转换为 512 × 512,块大小为 64 × 64,即 M = 512 和 m = 64。因此,图像哈希长度为
N
=
(
M
/
m
)
2
=
64
N = (M/m)^2 = 64
N=(M/m)2=64个整数。
可以看出QSVD的性能较好,但是不看旋转。对于旋转裁剪操作的AUC值只有0.71144,而其他操作的AUC值都接近1。
主要代码
import numpy as np #1.20.3
import quaternion as qt
import cv2
import matplotlib.pyplot as plt
import os
import pandas as pd
import imageio
def readImg(im_fn):
im = cv2.imread(im_fn)
if im is None:
# print('{} cv2.imread failed'.format(im_fn))
tmp = imageio.mimread(im_fn)
if tmp is not None:
imt = np.array(tmp)
imt = imt[0]
im = imt[:, :, 0:3]
im=cv2.cvtColor(im, cv2.COLOR_RGB2BGR)
return im
def read_images_from_folder(folder_path):
"""
读取文件夹中所有的图片
"""
image_list = []
image_paths = [] # 用于保存图片的文件路径
# 遍历文件夹中的所有文件
for filename in os.listdir(folder_path):
file_path = os.path.join(folder_path, filename)
# 检查文件是否为图片
if file_path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp','.tif')):
try:
# 使用OpenCV读取图片
image = readImg(file_path)
image_list.append(image)
image_paths.append(file_path)
except Exception as e:
# 处理异常,例如无法读取的文件
print(f"Error reading image {file_path}: {e}")
return image_list, image_paths
def preprocessing(image, M=512):
"""
数据预处理
"""
# 1.使用双线性插值将图片大小调整为标准大小M×M
img_resized = cv2.resize(image, (M, M))
# 2.对图片使用3×3的高斯低通滤波,减轻JPEG压缩和噪声污染等微小操作队图像哈希的影响。
kernel = np.array([[1, 2, 1],
[2, 4, 2],
[1, 2, 1]]) / 16.0
# 对每一个颜色通道应用滤波
img_Gaussian = cv2.filter2D(img_resized, -1, kernel)
# #应用7x7的平均滤波器
# k_size = 14
# img_blurred = cv2.blur(img_Gaussian, (k_size, k_size))
# 3.将BGR转为RGB
# RGB_image = cv2.cvtColor(img_Gaussian, cv2.COLOR_BGR2RGB)
# #4.将BGR转LAB
Lab_image = cv2.cvtColor(img_Gaussian, cv2.COLOR_BGR2LAB)
# #4.将BGR转HSV
# HSV_image=cv2.cvtColor(img_Gaussian,cv2.COLOR_BGR2HSV)
#
# #4.将BGR转HLS
# HLS_image=cv2.cvtColor(img_Gaussian,cv2.COLOR_BGR2HSV)
return Lab_image
def qua2com2(Q):
a1 = Q[:, :, 0] + Q[:, :, 1]*1j
a2 = Q[:, :, 2] + Q[:, :, 3]*1j
A = np.array([[a1, a2], [-np.conj(a2), np.conj(a1)]])
return A
def QSVD(Q):
# 调用 qua2com2 函数将四元数矩阵转换为复数矩阵
A = qua2com2(Q)
# 对复数矩阵 A 进行奇异值分解
Uc, Sc, Vc = np.linalg.svd(A)
# 获取对角线上一半的奇异值
if Sc.shape[0] > Sc.shape[1]:
Sq = np.sum(Sc, axis=1)
else:
Sq = np.sum(Sc, axis=0)
Sq = Sq[0::2]
Sq = Sq.reshape(1, -1) # 奇异值
# 对奇异值进行排序
IX = np.argsort(-np.abs(Sq))
Sq = Sq[0, IX]
return Sq
def get_hash(img):
###Local feature extraction via QSVD
## 1.create the quaternion representation of the image
lab_image=preprocessing(img)
N, M, D = lab_image.shape
# print(N, M, D)
Q = np.zeros((N, M, D + 1))
Q[:, :, 1:] = lab_image
## 2.Non-overlapping chunking of preprocessed quaternion matrices
blockSize = 64; # 定义块大小
numBlocks = int(N // blockSize)
p1 = np.zeros(blockSize)
p2 = np.zeros(blockSize)
for i in range(numBlocks):
for j in range(numBlocks):
# 计算块的起始索引与结束索引
rowStart = i * blockSize
rowEnd = (i + 1) * blockSize
colStart = j * blockSize
colEnd = (j + 1) * blockSize
# print(rowStart,rowEnd,colStart,colEnd)
Sq = QSVD(Q[rowStart:rowEnd, colStart:colEnd, :])
p1[i * numBlocks + j] = Sq[0, 0]
p2[i * numBlocks + j] = Sq[0, 1]
###归一化
x = (p1 - np.mean(p1)) / np.std(p1)
y = (p2 - np.mean(p2)) / np.std(p2)
# 计算参考点(分别为x和y的平均值)
x_mean = np.mean(x)
y_mean = np.mean(y)
# 计算欧氏距离
d = np.sqrt((x - x_mean) ** 2 + (y - y_mean) ** 2)
# 浮点数量化为浮点数
h = np.fix(d * 100 + 0.5).astype(int)
return h