使用OpenCV实现以图搜图

您所在的位置:网站首页 怎么搜图找图 使用OpenCV实现以图搜图

使用OpenCV实现以图搜图

2024-07-12 02:33| 来源: 网络整理| 查看: 265

使用OpenCV实现以图搜图 什么是以图搜图?感知哈希算法算法实现步骤效果源码

什么是以图搜图?

以图搜图,简单来说,就是通过搜索图像的文本或视觉特征,帮助用户找到与这张图片相似或相关的其他图形图像资料。

感知哈希算法

感知哈希算法(Perceptual Hashing Algorithm,简称PHA或PHash)是一种用于检测非结构化数据(如图像、视频、音频)相似性的技术。其原理是利用数据的频谱特征来描述对象,并通过一定的数学方法计算出一个哈希码(Hash String),以此来表示该对象的特征。当数据的频谱特征发生变化时,其对应的哈希码也会相应改变。

算法实现步骤

感知哈希算法实现步骤主要包括以下几步:

缩小尺寸:将图像缩小到一定的尺寸,比如8x8,总共64个像素。这一步的目的是去除图像的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图像差异。简化色彩:将缩小后的图像转为灰度图,即所有像素点都转换为灰度值。简化色彩有助于突出图像的主要特征,降低计算的复杂度。计算平均值:计算所有像素的灰度平均值。这个平均值将作为后续比较像素灰度的基准。比较像素灰度:将每个像素的灰度值与平均值进行比较。如果像素的灰度值大于或等于平均值,则记录为1,否则记录为0。计算哈希值:将上一步的比较结果组合在一起,形成一个固定长度的哈希值。这个哈希值就是图像的“指纹”,代表了图像的主要特征。对比图片指纹:在生成了每个图像的哈希值(即指纹)之后,就可以开始对比不同的图片指纹了。通常,会计算两个指纹之间的差异度,例如,通过比较两个哈希值中不同位的数量。如果差异度低于某个预设的阈值,就认为这两张图片是相似的;如果差异度高于阈值,则认为它们是不同的图片。 效果

要搜索的图片: 在这里插入图片描述 搜索的图片库: 在这里插入图片描述 匹配出3个最接近的图片: 在这里插入图片描述

源码 import glob import cv2 import numpy as np import matplotlib.pyplot as plt # ------------------ 辅助函数 ------------------ def resize_and_grayscale(image, size=(8, 8)): """将图像缩放并转换为灰度图。""" resized = cv2.resize(image, size) gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY) return gray def compute_hash(image, size=(8, 8)): """计算图像的感知哈希值。""" gray = resize_and_grayscale(image, size) mean = np.mean(gray) binary = (gray > mean).astype(int) return binary.flatten() def compute_hamming_distance(hash1, hash2): """计算两个哈希值之间的汉明距离。""" xor = np.bitwise_xor(hash1, hash2) return np.sum(xor) def load_images_from_folder(folder, extensions=('jpg', 'jpeg', 'gif', 'png', 'bmp')): """从指定文件夹加载图像,并返回图像文件名和哈希值的列表。""" images = [] for ext in extensions: images.extend(glob.glob(f'{folder}/*.{ext}')) hashes = {img_path: compute_hash(cv2.imread(img_path)) for img_path in images} return hashes # ------------------ 主程序 ------------------ def main(): # 设置检索图像路径 query_image_path = "img_2.png" query_image = cv2.imread(query_image_path) if query_image is None: print(f"Error: Unable to load query image {query_image_path}") return query_hash = compute_hash(query_image) print(f"检索图像的感知哈希值为:\n{query_hash}") # 加载指定文件夹下的所有图像及其哈希值 image_hashes = load_images_from_folder('img') # 找出最相似的图像 distances = [(compute_hamming_distance(query_hash, image_hash), image_path) for image_path, image_hash in image_hashes.items()] sorted_distances = sorted(distances) # 绘制结果 fig, axs = plt.subplots(1, 4, figsize=(12, 4)) axs[0].imshow(cv2.cvtColor(query_image, cv2.COLOR_BGR2RGB)) axs[0].set_axis_off() axs[0].set_title("Query Image") for i, (distance, image_path) in enumerate(sorted_distances[:3], start=1): image = cv2.imread(image_path) axs[i].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) axs[i].set_axis_off() axs[i].set_title(f"Result {i} - Distance: {distance}") plt.tight_layout() plt.show() if __name__ == "__main__": main()


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3