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

文章信息
  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_idef 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 ycropped_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 ycropped_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]])/16out = cv2.filter2D(img, -1 , kernel=kernel)  # 二维滤波器# out = cv2.cvtColor(out, cv2.COLOR_BGR2RGB)out = cv2.cvtColor(out, cv2.COLOR_BGR2HSV)return outdef local_feature_gen(img, sigma, n_components):"""iamge:(512,512,3)return: 降维之后的图像(d, N)"""from sklearn.decomposition import PCA, KernelPCAN_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.Tdef 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)) / NK = 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.shaper, b, g = img[:,:,0], img[:,:,1], img[:,:,2]R = r - (g + b)/2G = g - (r + b)/2B = b - (r + g)/2Y = (r + g)/2 - (abs(r - g))/2 - bRG = R - GBY =B - YI1 = ((r+g+b) /3)M = np.zeros((h, w))f1 = M + RG * 1jf2 = BY + I1 * 1jF1 = 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 outdef 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) * 1000result.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 resultdef glcm(img, levels = 32):'''https://www.cnblogs.com/xiaoliang-333/articles/16937977.htmlgraycom = 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, graycopropsimg = img.astype(np.float64)img = img * levels / 256.0img = img.astype(np.uint8)distances = [1, 1, 1, 1]  angles = [0, 45, 90, 135] #初始化一个空列表来存储GLCM矩阵统计特征glcms = []#为每个距离和角度组合计算 GLCMfor 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 glcmsdef 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.mzph.cn/web/2504.shtml

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

相关文章

学习Rust的第10天:枚举和模式匹配

今天我们来看看一个类似的概念 enums 。 Enums: We saw that in Rust, enums are data types that list possible values, giving a simple and type-safe mechanism to describe alternatives. We looked at how to create enums and use them to represent similar possibili…

webpack中mode、NODE_ENV、DefinePlugin、cross-env的使用

本文讲的全部知识点&#xff0c;都是和webpack相关的。如果你之前有疑问&#xff0c;那本文一定能帮你搞清楚。 问题来源一般是类似下面代码&#xff08;webpack.json中&#xff09;&#xff1a; "scripts": {"dev": "cross-env NODE_ENVdevelopmen…

opencv android 使用笔记

目录 获取app路径&#xff1a; 下载&#xff1a;OpenCV-android-sdk cmakelist配置&#xff1a; 头文件路径&#xff1a; 编译报错&#xff1a;clang: error: linker command failed with exit code 1 (use -v to see invocation) 读取图片例子 保存mp4 获取app路径&am…

自定义一个RedisTemplate

1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis&…

springcloud Ribbon的详解

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

<前端>Electron-builder为公证后的app打更新信息latest.yml

MacOS下&#xff0c;Electron-builder可以很方便的为测试包app打更新信息&#xff08;latest-mac.yml&#xff09;。 但是&#xff0c;正式发布的时候&#xff0c;不可能用测试包app&#xff0c;因为还没有进行公证。如何为公证的app打latest-mac.yml呢。 其实观察latest-mac.y…

Keil和VSCode协同开发STM32程序

系列文章 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. 配置环境 2. 测试打开工程 3. 测试编译工程 随着项目的复杂度上升&#xff0c;开发者不仅需要强大的硬件支持&#xff0c;还需要一个高效和灵活的开发环境。 vscode是一款集成大量可以便携开发插件的代码…

C++中的list类模拟实现

目录 list类模拟实现 list类节点结构设计 list类非const迭代器结构设计 迭代器基本结构设计 迭代器构造函数 operator()函数 operator*()函数 operator!()函数 operator(int)函数 operator--()函数 operator--(int)函数 operator()函数 operator->()函数 list…

TiDB 6.x 新特性解读 | Collation 规则

对数据库而言&#xff0c;合适的字符集和 collation 规则能够大大提升使用者运维和分析的效率。TiDB 从 v4.0 开始支持新 collation 规则&#xff0c;并于 TiDB 6.0 版本进行了更新。本文将深入解读 Collation 规则在 TiDB 6.0 中的变更和应用。 引 这里的“引”&#xff0c;…

Modbus转Profinet网关接称重设备与工控机通讯

Modbus转Profinet网关&#xff08;XD-MDPN100&#xff09;是一种能够实现Modbus协议和Profinet协议之间转换的设备。Modbus转Profinet网关可提供单个或多个RS485接口&#xff0c;使得不同设备之间可以顺利进行通信&#xff0c;进一步提升了工业自动化程度。 通过使用Modbus转Pr…

相亲平台app小程序

相亲平台app小程序是一种基于手机应用的微型程序&#xff0c;专为在线相亲交友活动设计。它提供了一系列的功能&#xff0c;旨在帮助用户更方便、更高效地找到心仪的伴侣。 首先&#xff0c;用户可以在个人资料部分上传照片、填写个人资料、设置兴趣爱好等信息&#xff0c;以便…

Electron+Vue3+ElectronForge整合 - 打包时整合 -分步打包

说明 本文介绍一下 Electron Vue3 的打包整合的基本操作。实现的效果是 &#xff1a; 1、一个正常的Vue3项目&#xff1b; 2、整合加入 Electron 框架 &#xff1a;开发时 Electron 加载的是开发的vue项目&#xff1b; 3、完成打包时整合&#xff1a;3.1 先完成vue3项目的正常…

Laravel 6 - 第十一章 中间件

​ 文章目录 Laravel 6 - 第一章 简介 Laravel 6 - 第二章 项目搭建 Laravel 6 - 第三章 文件夹结构 Laravel 6 - 第四章 生命周期 Laravel 6 - 第五章 控制反转和依赖注入 Laravel 6 - 第六章 服务容器 Laravel 6 - 第七章 服务提供者 Laravel 6 - 第八章 门面 Laravel 6 - …

深度解析:云计算的三宝——IaaS、PaaS和SaaS

4月22日&#xff0c;腾讯宣布旗下协作SaaS产品全面接入腾讯混元大模型&#xff0c;除去企业微信、腾讯会议、腾讯文档等“一门三杰”产品&#xff0c;腾讯乐享、腾讯电子签、腾讯问卷、腾讯云AI代码助手等协作SaaS产品也都已实现智能化升级。大模型应用落地再加速。 那么什么是…

2024年深圳杯东三省数学建模联赛A题论文首发第二种思路

深圳杯A题论文代码分享资料链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1L2NVgoefSW-yuqZjEB3wcw 提取码&#xff1a;sxjm 问题一 数据转换&#xff1a; 首先&#xff0c;我们将监测站的经纬度坐标转换为基于米的笛卡尔坐标系。这是因为在地面上的大尺度距离…

HarmonyOS开发案例:【音乐播放器】

介绍 使用ArkTS语言实现了一个简易的音乐播放器应用&#xff0c;主要包含以下功能&#xff1a; 播放应用中的音频资源文件&#xff0c;并可进行上一曲、下一曲、播放、暂停、切换播放模式&#xff08;顺序播放、单曲循环、随机播放&#xff09;等操作。结合后台任务管理模块&…

安全小课堂丨什么是暴力破解?如何防止暴力破解

什么是暴力破解&#xff1f; 暴力破解也可称为穷举法、枚举法&#xff0c;是一种比较流行的密码破译方法&#xff0c;也就是将密码进行一一推算直到找出正确的密码为止。比如一个6位并且全部由数字组成的密码&#xff0c;可能有100万种组合&#xff0c;也就是说最多需要尝试10…

JWT原理解析

一、概述 虽然现在很多的开发框架会支持JWT的使用&#xff0c;但是对JWT还是没有一个详细的了解&#xff0c;有很多疑惑&#xff1a; JWT比之前的session或者token有什么好处&#xff1f;JWT的构成元素是什么&#xff1f;JWT从生成到使用的详细流程&#xff1f; 二、 JWT 2…

SPI Flash and External SPI RAM(基于ESP32)

主要参考资料&#xff1a; 乐鑫ESP-IDF资料SPI Flash API: https://docs.espressif.com/projects/esp-idf/zh_CN/v5.1/esp32s3/api-reference/peripherals/spi_flash/index.html 乐鑫ESP-IDF资料SPI Flash and External SPI RAM Configuration: https://docs.espressif.com/pro…

场景 - 分库分表

分什么 数据量大分表&#xff0c;并发大分库 分表字段如何选择 如果对交易订单进行分表&#xff0c;可以选择的东西很多&#xff0c;比如说商户id&#xff0c;用户id&#xff0c;地区等等 分表的时候要考虑到数据倾斜问题 数据倾斜 比如说按商户号进行分表&#xff0c;一共…