图像哈希:全局+局部提取特征

文章信息
  1. 作者:梁小平,唐振军
  2. 期刊:ACM Trans. Multimedia Comput. Commun. Appl(三区)
  3. 题目:Robust Hashing via Global and Local Invariant Features for Image Copy Detection
目的、实验步骤及结论
  1. 目的:通过全局和局部提取特征来生成最终图像的哈希值。

  2. 实验步骤:
    在这里插入图片描述

    • 数据预处理:双线性插值(512 * 512)
    • 全局特征:
      • PDFT生成显著图S
      • 对GLCM使用四种参数(不同的角度)得到四个矩阵,每个矩阵得到4个统计特征,得到 1 * 16 的全局特征向量
    • 局部特征:
      • 使用HSV中的V分量,分块(64 * 64),将每一个块拼接成一个列向量,使用KPCA后得到d * N的矩阵。
      • 计算每一个矩阵维度的均值作为参考向量,计算所有向量(每一列)和参考向量的距离作为局部特征
    • 生成哈希值:将全局特征和局部特征进行拼接,使用量度排序作为最后的哈希值(长度为N+16)。
    • 相似性评价:使用汉明距离判断两张图片是否一致,若小于阈值则是相同图片。
  3. 结论

    • 首次提出KPCA应用于图像哈希
    • 适用于混合攻击
    • 全局特征对几何攻击(尤其是缩放和旋转)很敏感,而局部特征无法保持全局上下文信息导致判别效果不佳。
    • 使用全局和局部结合特征可以更加有利于互补进行提取特征。

本篇论文的实现代码如下:

def image_hash(img_path):
    img = processing(img_path)
    global_feature = global_feature_gen(img)
    local_feature = local_feature_gen(img, 10000, 4)
    h_i = gen_hashing(global_feature, local_feature)
    return h_i

def processing(img_path):
    """
    input:图片的路径
    output:处理后的RGB图片
    """
    try:
        img = cv2.imread(img_path)
        x = img.shape[0]//2 # 高度
        y = img.shape[1]//2 # 宽度
        Min = x if x<y else y
        cropped_image = img[x-Min:x+Min, y-Min:y+Min] # 裁剪图像
        img = cv2.resize((cropped_image), (512,512), interpolation=cv2.INTER_LINEAR)
    except:
        img = imageio.mimread(img_path)
        img = np.array(img)
        img = img[0]
        img = img[:, :, 0:3]
        x = img.shape[0]//2 # 高度
        y = img.shape[1]//2 # 宽度
        Min = x if x<y else y
        cropped_image = img[x-Min:x+Min, y-Min:y+Min, :] # 裁剪图像
        img = cv2.resize((cropped_image), (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_BGR2RGB)
    out = cv2.cvtColor(out, cv2.COLOR_BGR2HSV)
    return out

def local_feature_gen(img, sigma, n_components):
    """
    iamge:(512,512,3)
    return: 降维之后的图像(d, N)
    """
    from sklearn.decomposition import PCA, KernelPCA
    N_list = []
    V = img[:,:,2]
    for i in range(0,V.shape[0],64):
        for j in range(0,V.shape[1],64):
            image_block = V[i:i+64, j:j+64]
            N_list.append(image_block.reshape(-1)[:])
    N_list = np.array(N_list).copy()
    # kernel_pca = KernelPCA(n_components=4, kernel="poly", gamma=10)
    # result = kernel_pca.fit_transform(N_list)
    result = kpca(N_list, sigma, 4).copy()
    return result.T
    
def gaussian_kernel(X, sigma):
    sq_dists = pdist(X, 'sqeuclidean')  # 计算所有样本点之间的平方欧式距离
    mat_sq_dists = squareform(sq_dists)  # 转换成矩阵形式
    return np.exp(-mat_sq_dists / (2 * sigma**2))  # 计算高斯核矩阵

def kpca(X, sigma, n_components):
    # 步骤1: 计算高斯核矩阵
    K = gaussian_kernel(X, sigma)
    # 步骤2: 中心化核矩阵
    N = K.shape[0]
    one_n = np.ones((N, N)) / N
    K = K - one_n.dot(K) - K.dot(one_n) + one_n.dot(K).dot(one_n)
    # 步骤3: 计算特征值和特征向量
    eigenvalues, eigenvectors = eigh(K)
    eigenvalues, eigenvectors = eigenvalues[::-1], eigenvectors[:, ::-1]  # 降序排列
    # 步骤4: 提取前n个特征向量
    alphas = eigenvectors[:, :n_components]
    lambdas = eigenvalues[:n_components]
    return alphas / np.sqrt(lambdas)  # 归一化特征向量

def global_feature_gen(img):
    P = pqft(img)
    return P
def pqft(img, sigma=8):
    h, w, channel = img.shape
    r, b, g = img[:,:,0], img[:,:,1], img[:,:,2]
    R = r - (g + b)/2
    G = g - (r + b)/2
    B = b - (r + g)/2
    Y = (r + g)/2 - (abs(r - g))/2 - b
    RG = R - G
    BY =B - Y
    I1 = ((r+g+b) /3)
    M = np.zeros((h, w))
    f1 = M + RG * 1j
    f2 = BY + I1 * 1j
    F1 = np.fft.fft2(f1)
    F2 = np.fft.fft2(f2)
    phaseQ1 = np.angle(F1)
    phaseQ2 = np.angle(F2)
    ifftq1 = np.fft.ifft2(np.exp(phaseQ1 * 1j))
    ifftq2 = np.fft.ifft2(np.exp(phaseQ2 * 1j))
    absq1 = np.abs(ifftq1)
    absq2 = np.abs(ifftq2)
    squareq=(absq1+absq2) * (absq1+absq2)
    out = cv2.GaussianBlur(squareq, (5, 5), sigma)
    out = cv2.normalize(out.astype('float'), None, 0, 255, cv2.NORM_MINMAX)
    return out

def gen_hashing(global_feature, local_feature):
    """
    先求出列均值,在算出每一列之间的距离,最后使用序数度量来代表哈希值
    input:array (x,64,64)
    output:list (x)
    """
    result = glcm(global_feature)
    y_mean = np.mean(local_feature, axis = 0)
    z = np.sqrt((y_mean[1:] - y_mean[:-1]) ** 2) * 1000
    result.extend(z)
    sorted_indices = sorted(range(len(result)), key=lambda i: result[i])
    result = [sorted_indices.index(i)+1 for i in range(len(result))]
    return result
    
def glcm(img, levels = 32):
    '''
    https://www.cnblogs.com/xiaoliang-333/articles/16937977.html
    graycom = greycomatrix(img, [1], [0, np.pi/4, np.pi/2, np.pi*3/4], levels=256)
    c = feature.greycoprops(graycom, 'contrast')  # 对比度
    d = feature.greycoprops(graycom, 'dissimilarity')   # 相异性
    h = feature.greycoprops(graycom, 'homogeneity')    # 同质性
    e = feature.greycoprops(graycom, 'energy')    # 能量
    corr = feature.greycoprops(graycom, 'correlation')    # 相关性
    ASM = feature.greycoprops(graycom, 'ASM')     # 角二阶矩
    '''
    from skimage.feature import graycomatrix, graycoprops
    img = img.astype(np.float64)
    img = img * levels / 256.0
    img = img.astype(np.uint8)
    distances = [1, 1, 1, 1]  
    angles = [0, 45, 90, 135] 
    #初始化一个空列表来存储GLCM矩阵统计特征
    glcms = []
    #为每个距离和角度组合计算 GLCM
    for d,a in zip(distances,angles):
        glcm = graycomatrix(img,distances=[d],angles=[a],levels=levels,symmetric=True, normed=True)
        contrast = graycoprops(glcm, 'ASM')     
        glcms.append(contrast[0, 0])
        
        correlation = graycoprops(glcm, 'contrast')  
        glcms.append(correlation[0, 0])
        
        energy = graycoprops(glcm, 'correlation')    
        glcms.append(energy[0, 0])
        
        homogeneity = graycoprops(glcm, 'homogeneity')    
        glcms.append(homogeneity[0, 0])
    # return np.array(np.round(glcms), dtype=np.uint8)
    return glcms

def dist_img(h1,h2):
    # distance = np.count_nonzero(np.array(list(h1)) != np.array(list(h2)))
    # return distance / len(h1)
    h1 = np.array(h1)
    h2 = np.array(h2)
    return sum(np.abs(h1-h2))/len(h1)

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

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

相关文章

CPPTest实例分析(C++ Test)

1 概述 CppTest是一个可移植、功能强大但简单的单元测试框架&#xff0c;用于处理C中的自动化测试。重点在于可用性和可扩展性。支持多种输出格式&#xff0c;并且可以轻松添加新的输出格式。 CppTest下载地址&#xff1a;下载地址1  下载地址2 下面结合实例分析下CppTest如…

进程概念(进程第1篇)【Linux复习篇】

目录 1、冯诺依曼体系结构怎么画&#xff1f;中央处理器是什么&#xff1f;存储器是什么&#xff1f;每个部分有什么作用&#xff1f; 2、什么是操作系统&#xff1f; 3、什么叫进程&#xff1f;操作系统如何管理进程的&#xff1f; 4、怎么查看进程&#xff1f; 5、C语言…

springcloud Ribbon的详解

1、Ribbon是什么 Ribbon是Netflix发布的开源项目&#xff0c;Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的框架。 2、Ribbon能干什么 LB负载均衡(Load Balance)是什么&#xff1f;简单的说就是将用户的请求平摊的分配到多个服务上&#xff0c;从而达…

AI视频改字个性化祝福豪车装X系统uniapp前端开源源码下载

装X系统源码简介 创意无限&#xff01;AI视频改字祝福&#xff0c;豪车装X系统源码开源&#xff0c;打造个性化祝福视频不再难&#xff01; 想要为你的朋友或家人送上一份特别的祝福&#xff0c;让他们感受到你的真诚与关怀吗&#xff1f;现在&#xff0c; 通过开源的AI视频…

从0到1—POC编写基础篇(二)

接着上一篇 POC常用基础模块 urllib 模块 Python urllib 库用于操作网页 URL&#xff0c;并对网页的内容进行抓取处理。 urllib 包 包含以下几个模块&#xff1a; ●urllib.request - 打开和读取 URL。 ●urllib.error - 包含 urllib.request 抛出的异常。 ●urllib.parse - …

新技术前沿-2024-大型语言模型LLM的本地化部署

参考快速入门LLM 参考究竟什么是神经网络 1 深度学习 1.1 神经网络和深度学习 神经网络是一种模拟人脑神经元工作方式的机器学习算法,也是深度学习算法的基本构成块。神经网络由多个相互连接的节点(也称为神经元或人工神经元)组成,这些节点被组织成层次结构。通过训练,…

【网络安全】在网络中如何对报文和发送实体进行鉴别?

目录 1、报文鉴别 &#xff08;1&#xff09;使用数字签名进行鉴别 &#xff08;2&#xff09;密码散列函数 &#xff08;3&#xff09;报文鉴别码 2、实体鉴别 鉴别(authentication) 是网络安全中一个很重要的问题。 一是要鉴别发信者&#xff0c;即验证通信的对方的确是…

小扎宣布开放 Meta Horizo​​n OS

日前&#xff0c;Meta以“混合现实的新时代”为题的博文宣布向第三方制造商开放Meta Horizon OS&#xff0c;包括华硕、联想和微软Xbox等等&#xff1a; Meta正在朝着为元宇宙建立一个更开放的计算平台的愿景迈出下一步。Meta正在向第三方硬件制造商开放赋能Meta Quest设备的操…

使用 IPAM 解决方案简化分布式网络管理

随着组织在数字领域的全球扩张&#xff0c;分布式网络是不可避免的&#xff0c;这意味着&#xff0c;随着 IT 基础设施的发展&#xff0c;组织需要适应&#xff0c;这包括在不断增长的系统需求、应用程序堆栈、各种协议和安全防御中监控、现代化和简化流程和资源。在有效管理现…

AJAX——案例

1.商品分类 需求&#xff1a;尽可能同时展示所有商品分类到页面上 步骤&#xff1a; 获取所有的一级分类数据遍历id&#xff0c;创建获取二级分类请求合并所有二级分类Promise对象等待同时成功后&#xff0c;渲染页面 index.html代码 <!DOCTYPE html> <html lang&qu…

Pycharm代码规范与代码格式化插件安装

给大家分享两个PyCharm编辑器的插件&#xff0c;分别是pylint与autopep8&#xff0c;主要用来提高我们在使用python进行自动化测试编写以及性能测试脚本编写过程中的代码质量、可读性与美观性。 pylint&#xff1a; ● 代码检查工具&#xff1a;它可以帮助检查代码中的错误、…

pnpm 安装后 node_modules 是什么结构?为什么 webpack 不识别 pnpm 安装的包?

本篇研究&#xff1a;使用 pnpm 安装依赖时&#xff0c;node_modules 下是什么结构 回顾 npm3 之前&#xff1a;依赖树 缺点&#xff1a; frequently packages were creating too deep dependency trees, which caused long directory paths issue on Windowspackages were c…

明日方舟游戏助手:一键完成日常任务 | 开源日报 No.233

MaaAssistantArknights/MaaAssistantArknights Stars: 11.6k License: AGPL-3.0 MaaAssistantArknights 是一款《明日方舟》游戏的小助手&#xff0c;基于图像识别技术&#xff0c;支持一键完成全部日常任务。 刷理智、掉落识别及上传企鹅物流智能基建换班、自动计算干员效率…

《ElementPlus 与 ElementUI 差异集合》el-select 差异点,如:高、宽、body插入等

宽度 Element UI 父元素不限制宽度时&#xff0c;默认有个宽度 207px&#xff1b; 父元素有固定宽度时&#xff0c;以父元素宽度为准&#xff1b; Element Plus 父元素不限制宽度时&#xff0c;默认100%&#xff1b; 父元素有固定宽度时&#xff0c;以父元素宽度为准&#x…

哪些因素影响了PCB电路板切割精度?

PCB电路板切割是电子制造过程中一个至关重要的环节&#xff0c;其精度对后续工序的质量和效率具有决定性影响。因此&#xff0c;了解影响PCB电路板切割精度的原因&#xff0c;对于提高电子产品的质量和生产效率具有重要意义。 1. PCB分板机稳定性 PCB分板机的性能直接影响到切…

李沐62_序列到序列学习seq2seq——自学笔记

"英&#xff0d;法”数据集来训练这个机器翻译模型。 !pip install --upgrade d2l0.17.5 #d2l需要更新import collections import math import torch from torch import nn from d2l import torch as d2l循环神经网络编码器。 我们使用了嵌入层&#xff08;embedding l…

广东理工学院携手泰迪智能科技成功部署人工智能实验室

广东理工学院是经国家教育部批准设立的全日制普通本科院校&#xff0c;入选全国应用型人才培养工程培养基地、国家级众创空间试点单位、广东省高校电子商务人才孵化基地。开设34个本科专业&#xff0c;涵盖工学、经济学、管理学、文学、艺术学、教育学等6大学科门类&#xff0c…

【docker】拉取人大金仓KingbaseES数据库镜像速度很慢问题

作为一种新兴的虚拟化方式&#xff0c;Docker 跟传统的虚拟化方式相比具有众多的优势。 对于学习新技术、快速搭建实验环境等是很不错的选择。优势大致总结如下&#xff1a; 1.镜像拉取速度对比 速度前后对比&#xff0c;提升10倍不止&#xff0c;很快将镜像文件下载至本地。 …

Java常见面试题总结

文章目录 1. 什么是线程和进程?2. 请简要描述线程与进程的关系,区别及优缺点&#xff1f;3. 什么是堆和方法区&#xff1f;4. 并发与并行的区别5. 同步和异步的区别6.为什么要使用多线程? 优点&#xff1f;&#xff08;重要&#xff09;7. 使用多线程可能带来什么问题?8. 如…

python爬虫 - 爬取html中的script数据(zum.com新闻信息 )

文章目录 1. 分析页面内容数据格式2. 使用re.findall方法&#xff0c;编写爬虫代码3. 使用re.search 方法&#xff0c;编写爬虫代码 1. 分析页面内容数据格式 &#xff08;1&#xff09;打开 https://zum.com/ &#xff08;2&#xff09;按F12&#xff08;或 在网页上右键 --…