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

news2025/1/9 1:53:41
文章信息
  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)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式与一致性协议之拜占庭将军问题(三)

拜占庭将军问题 叛将先发送消息 如果是叛将楚先发送作战消息&#xff0c;干扰作战计划&#xff0c;结果会有所不同吗&#xff1f; 在第一轮作战信息协商中&#xff0c;楚向苏秦发送作战指令"进攻",向齐、燕发送作战指令"撤退"&#xff0c;如图所示(当然还…

排序算法:顺序查找

简介 顺序查找&#xff08;也称为线性查找&#xff09;是一种简单直观的搜索算法。按照顺序逐个比较列表或数组中的元素&#xff0c;直到找到目标元素或搜索完整个列表。 应用场景 数据集比较小&#xff0c;无需使用复杂的算法。数据集没有排序&#xff0c;不能使用二分查找…

springboot停机关闭前保证处理完请求

application.yml配置 server:shutdown: graceful // 处理完请求在关闭服务server:shutdown: immediate // 立刻关闭&#xff0c;默认 jvm关闭自带的回调

【QT学习】9.绘图,三种贴图,贴图的转换,不规则贴图(透明泡泡)

一。绘图的解释 Qt 中提供了强大的 2D 绘图系统&#xff0c;可以使用相同的 API 在屏幕和绘图设备上进行绘制&#xff0c;它主要基于QPainter、QPaintDevice 和 QPaintEngine 这三个类。 QPainter 用于执行绘图操作&#xff0c;其提供的 API 在 GUI 或 QImage、QOpenGLPaintDev…

Windows10如何关闭Edge浏览器的Copilot

在Windows10更新后&#xff0c;打开Edge浏览器&#xff0c;无论复制什么内容&#xff0c;都会弹出Copilot人工智能插件&#xff0c;非常令人反感&#xff0c;网上搜索的关闭方法都非常麻烦&#xff0c;比如&#xff1a;组策略和注册表。自己摸索得出最简便有效的关闭方法。 1、…

自然语言处理: 第二十八章大模型基底之llama3

项目地址: meta-llama/llama3: The official Meta Llama 3 GitHub site 前言 LLaMa系列一直是人们关注的焦点&#xff0c;Meta在4月18日发布了其最新大型语言模型 LLaMA 3。该模型将被集成到其虚拟助手Meta AI中。Meta自称8B和70B的LLaMA 3是当今 8B 和 70B 参数规模的最佳模…

【深度学习】YOLOv5,烟雾和火焰,目标检测,防火检测,森林火焰检测

文章目录 数据收集和数据标注查看标注好的数据的脚本下载yolov5创建 dataset.yaml训练参数开始训练yolov5n训练训练后的权重下载gradio部署 数据收集和数据标注 搜集数据集2w张。 pip install labelme labelme 然后标注矩形框和类别。 下载数据请看这里&#xff1a; https:…

Go 堆内存分配源码解读

简要介绍 在Go的内存分配中存在几个关键结构&#xff0c;分别是page、mspan、mcache、mcentral、mheap&#xff0c;其中mheap中又包括heapArena&#xff0c;具体这些结构在内存分配中担任什么角色呢&#xff1f; 如下图&#xff0c;可以先看一下整体的结构&#xff1a; mcach…

Jackson 2.x 系列【30】Spring Boot 集成之数据脱敏

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 本系列Spring Boot 版本 3.2.4 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 概述2. 实现思路3. 案例演示3.1 脱敏规则3.2 自…

SpringBoot学习之Kafka发送消费消息入门实例(三十五)

使用Kafka之前需要先启动fKafka,如何下载安装启动kafka请先参考本篇文章的前两篇: 《SpringBoot学习之Kafka下载安装和启动【Windows版本】(三十四)》 《SpringBoot学习之Kafka下载安装和启动【Mac版本】(三十三)》 一、POM依赖 1、加入kafka依赖 2、我的整个POM代码…

docker容器技术篇:容器集群管理实战mesos+zookeeper+marathon(一)

容器集群管理实战mesoszookeepermarathon&#xff08;一&#xff09; mesos概述 1.1 Mesos是什么 Apache Mesos 是一个基于多资源调度的集群管理软件&#xff0c;提供了有效的、跨分布式应用或框架的资源隔离和共享&#xff0c;可以运行 Hadoop、Spark以及docker等。 1.2 为…

银河麒麟V10 SP1服务器客户端定时数据同步

银河麒麟V10 SP1服务器客户端定时数据同步 0.概述 当前只测试了将数据从客户端往服务端推送&#xff0c;两个客户端分别推送不同的数据 1.环境 三台电脑均为银河麒麟V10SP1桌面操作系统 服务器IP&#xff1a;192.168.1.51 用户名&#xff1a;wlh 客户端IP&#xff1a;192…

C语言Linux vim shell命令

无论是在插入模式或者是其他模式下对于文件的修改都是对于内存缓冲区进行修改&#xff0c;只有当点击w进行保存以后才会将数据写入到一个新的文件中的&#xff0c;将源文件删除&#xff0c;并且新文件改为文件的名字 1. actionmotion dG删到文件尾 ggdG先到开头再删除到末尾…

微服务项目实战-黑马头条(八):App端-文章ES搜索、MongoDB搜索记录和关键词联想

文章目录 一、今日内容介绍1.1 App端搜索-效果图1.2 今日内容 二、搭建ElasticSearch环境2.1 拉取镜像2.2 创建容器2.3 配置中文分词器 ik2.4 使用postman测试 三、app端文章搜索3.1 需求分析3.2 思路分析3.3 创建索引和映射3.4 数据初始化到索引库3.4.1 导入es-init到heima-le…

光纤网络电力控制系统设计方案:623-6U CPCI的光纤网络电力控制系统

6U CPCI的光纤网络电力控制系统 一、设备概述 柔性直流输电系统中用于控制与测量的FS系统&#xff0c;适用于风电和太阳能发电的并网快速数值计算和闭环控制&#xff0c;以及与直流输电系统的换流器有关的特殊控制功能&#xff0c;包括门控单元的信号处理。该控制板的最大…

Tensorflow2.0笔记 - BatchNormalization

本笔记记录BN层相关的代码。关于BatchNormalization&#xff0c;可以自行百度&#xff0c;或参考这里&#xff1a; 一文读懂Batch Normalization - 知乎神经网络基础系列&#xff1a; 《深度学习中常见激活函数的原理和特点》《过拟合: dropout原理和在模型中的多种应用》深度…

ZYNQ--PL读写PS端DDR数据

PL 和PS的高效交互是zynq 7000 soc开发的重中之重&#xff0c;我们常常需要将PL端的大量数 据实时送到PS端处理&#xff0c;或者将PS端处理结果实时送到PL端处理&#xff0c;常规我们会想到使用DMA 的方式来进行&#xff0c;但是各种协议非常麻烦&#xff0c;灵活性也比较差&am…

【Linux-14】进程地址空间&虚拟空间&页表——原理&知识点详解

前言 大家好吖&#xff0c;欢迎来到 YY 滴 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…

k8s calico vxlan式详解

之前的文章讲了k8s ipip模式的使用以及流量路径&#xff0c;本篇文章主要是来讲解一下vxlan 模式下pod 流量是如何通信的。 一、ipip模式转vxlan 修改calico backend参数 将calico_backend参数由bird设置为vxlan,因为vxlan部署不使用bgp 修改calico controllers的configmap…

Linux安装redis(单机和集群)

一、单机安装 1.源码安装&#xff08;方式一&#xff09; 1.1 下载并上传tar包 将redis-6.2.6.tar.gz 上传到/home/data/install_pkg/redis下 1.2 解压缩 cd /home/data/install_pkg/redis //切到指定目录 tar -xvf redis-6.2.6.tar.gz //解压缩 1.3 编译安…