这个领域的背景
- 图像哈希的应用:图像检索、图像认证、数字水印、图像复制检测、篡改检测、图像索引、多媒体取证和降低参考图像质量评估。
- 图像哈希的五大类算法:DWT,DCT,DFT,radon变化,矩阵分解。
相关性质
- NMF的性质:Vn = B*Cn,原矩阵的一列相当于基矩阵乘系数矩阵的一列。
文章信息
- 作者:唐振军
- 期刊:IEEE TRANSACTIONS ON KNOWLEDGE AND DATA ENGINEERING(一区)
- 题目:Robust Perceptual Image Hashing Based on Ring Partition and NMF
目的、实验步骤及结论
-
目的:使用环形分区使得传统的NMF图像哈希抗旋转
-
实验步骤:
-
数据预处理:使用双线性插值(M*M),使用YCbCr空间中的Y通道(亮度信息)
-
特征提取:
-
构造环形分区,每一个环的面积一样,将长度不同的环进行插值,将所有环拼接成二次图像
-
针对二次图像使用NMF,得到系数矩阵C
-
-
构造哈希值:针对系数矩阵C进行拼接成行向量,得到哈希值
-
相似性评价:使用相关系数(Pearson相关系数)判断是否为同一张图片
-
-
结论:
使用环形分区之后生成的二次图像针对旋转攻击具有良好的鲁棒性。
小组件和核心理论
- 环形分区:这个组件能够很好地抵抗旋转攻击,不过有些算法使用了这个组件之后会导致其他攻击的鲁棒性下降。
- NMF:一种降维方式。
文章信息
- 作者:唐振军
- 期刊:JOURNAL OF UBIQUITOUS CONVERGENCE AND TECHNOLOGY
- 题目:Robust Image Hashing for Tamper Detection Using Non-Negative Matrix Factorization
目的、实验步骤及结论
-
目的:使用NMF实现图像哈希
-
实验步骤:
- 图像预处理:使用双线性插值(M*M),使用YCbCr空间中的Y通道(亮度信息)
- 特征提取:
- 随机划分t个条带,每个条带随机划分t个块,每个块再使用一次双线性插值(K * K),每一块堆叠成k^2*1的列向量,将所有列合并形成二次图像
- 构造哈希值:针对二次图像使用NMF得到系数矩阵C,按照某种规则生成二进制值,得到哈希值。
- 相似性评价:使用汉明距离来判断两张图片是否一致。
-
结论
这篇论文创新点就是使用了随机划分子带,再随机划分块,再使用插值算法。
以下是我复现论文的代码,供大家进行参考:
def image_hash(img_path,n,k):
img = processing(img_path,n)
C_r_list = image_feature(img,k)
h_i = gen_hashing(C_r_list)
return h_i
def processing(img_path,n):
"""
input:图片的路径
output:处理后的RGB图片
"""
try:
img = cv2.imread(img_path)
img = cv2.resize((img), (512,512), interpolation=cv2.INTER_LINEAR)
except:
img = imageio.mimread(img_path)
img = np.array(img)
img = img[0]
img = img[:, :, 0:3]
img = cv2.resize((img), (512,512), interpolation=cv2.INTER_LINEAR)
# out = cv2.GaussianBlur(img, (3, 3),1.3) # 使用python自带的高斯滤波
kernel = np.array([[1,2,1],[2,4,2],[1,2,1]])/16
out = cv2.filter2D(img, -1 , kernel=kernel) # 二维滤波器
out = cv2.cvtColor(out, cv2.COLOR_BGR2YCrCb)[:,:,0]
ring_img = ring_partition(out,n)
return ring_img
def ring_partition(img,n):
"""
使用环形分区形成二次图像
img:原始图片
n:环形分区
return:二次图像
"""
radius = [0]
u_a = int(np.floor((img.shape[0]/2) ** 2 * np.pi / n)/64)*64
radius.append(np.sqrt(u_a / np.pi))
Y_result = np.zeros((n,u_a))
for i in range(1,n):
radius.append(np.sqrt((u_a + np.pi * radius[i] ** 2) / np.pi))
# radius = np.ceil(radius)
for i in range(len(radius)-1):
inner_radius = radius[i]
outer_radius = radius[i+1]
ring_result = ring_value(img,inner_radius,outer_radius,u_a)
Y_result[i] = ring_result
return Y_result.T
def ring_value(img,inner_radius,outer_radius,u_a):
"""
获取环形分区中不为0的值,并且以升序的形式排序
return:(1,448)
"""
center = (img.shape[0],img.shape[0])
x,y = np.ogrid[0:img.shape[0],0:img.shape[0]]
distance = np.sqrt((x-img.shape[0]/2)**2 + (y-img.shape[0]/2)**2)
mask = (distance < outer_radius) & (distance >=inner_radius) # 获得在环形区域内的掩码
R = img[mask]
xp = np.linspace(1, len(R), len(R))
x = np.linspace(1, len(R), u_a)
result = np.sort(np.interp(x, xp, np.sort(R)))
return result
def image_feature(img_second,k):
"""
iamge:(512,512,3)
return: array格式(x,64,64)
"""
from sklearn.decomposition import NMF
model = NMF(n_components=k, init='random',solver = "mu",beta_loss = "kullback-leibler", random_state=0 , max_iter = 1000)
W = model.fit_transform(img_second)
H = model.components_
return H
def gen_hashing(feature_matrix):
"""
生成图像哈希值
input:array (x,64,64)
output:list (x)
"""
k,n = feature_matrix.shape
return np.array([feature_matrix[i][j] for i in range(k) for j in range(n)])
def dist_img(h1,h2):
return np.corrcoef(h1, h2)[0,1]