Python图片检索之以图搜图
作者:代码小白的成长 发布时间:2021-08-11 12:08:23
标签:Python,图片,检索
一、待搜索图
二、测试集
三、new_similarity_compare.py
# -*- encoding=utf-8 -*-
from image_similarity_function import *
import os
import shutil
# 融合相似度阈值
threshold1 = 0.70
# 最终相似度较高判断阈值
threshold2 = 0.95
# 融合函数计算图片相似度
def calc_image_similarity(img1_path, img2_path):
"""
:param img1_path: filepath+filename
:param img2_path: filepath+filename
:return: 图片最终相似度
"""
similary_ORB = float(ORB_img_similarity(img1_path, img2_path))
similary_phash = float(phash_img_similarity(img1_path, img2_path))
similary_hist = float(calc_similar_by_path(img1_path, img2_path))
# 如果三种算法的相似度最大的那个大于0.7,则相似度取最大,否则,取最小。
max_three_similarity = max(similary_ORB, similary_phash, similary_hist)
min_three_similarity = min(similary_ORB, similary_phash, similary_hist)
if max_three_similarity > threshold1:
result = max_three_similarity
else:
result = min_three_similarity
return round(result, 3)
if __name__ == '__main__':
# 搜索文件夹
filepath = r'D:\Dataset\cityscapes\leftImg8bit\val\frankfurt'
#待查找文件夹
searchpath = r'C:\Users\Administrator\Desktop\cityscapes_paper'
# 相似图片存放路径
newfilepath = r'C:\Users\Administrator\Desktop\result'
for parent, dirnames, filenames in os.walk(searchpath):
for srcfilename in filenames:
img1_path = searchpath +"\\"+ srcfilename
for parent, dirnames, filenames in os.walk(filepath):
for i, filename in enumerate(filenames):
print("{}/{}: {} , {} ".format(i+1, len(filenames), srcfilename,filename))
img2_path = filepath + "\\" + filename
# 比较
kk = calc_image_similarity(img1_path, img2_path)
try:
if kk >= threshold2:
# 将两张照片同时拷贝到指定目录
shutil.copy(img2_path, os.path.join(newfilepath, srcfilename[:-4] + "_" + filename))
except Exception as e:
# print(e)
pass
四、image_similarity_function.py
# -*- encoding=utf-8 -*-
# 导入包
import cv2
from functools import reduce
from PIL import Image
# 计算两个图片相似度函数ORB算法
def ORB_img_similarity(img1_path, img2_path):
"""
:param img1_path: 图片1路径
:param img2_path: 图片2路径
:return: 图片相似度
"""
try:
# 读取图片
img1 = cv2.imread(img1_path, cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread(img2_path, cv2.IMREAD_GRAYSCALE)
# 初始化ORB检测器
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# 提取并计算特征点
bf = cv2.BFMatcher(cv2.NORM_HAMMING)
# knn筛选结果
matches = bf.knnMatch(des1, trainDescriptors=des2, k=2)
# 查看最大匹配点数目
good = [m for (m, n) in matches if m.distance < 0.75 * n.distance]
similary = len(good) / len(matches)
return similary
except:
return '0'
# 计算图片的局部哈希值--pHash
def phash(img):
"""
:param img: 图片
:return: 返回图片的局部hash值
"""
img = img.resize((8, 8), Image.ANTIALIAS).convert('L')
avg = reduce(lambda x, y: x + y, img.getdata()) / 64.
hash_value = reduce(lambda x, y: x | (y[1] << y[0]), enumerate(map(lambda i: 0 if i < avg else 1, img.getdata())),
0)
return hash_value
# 计算两个图片相似度函数局部敏感哈希算法
def phash_img_similarity(img1_path, img2_path):
"""
:param img1_path: 图片1路径
:param img2_path: 图片2路径
:return: 图片相似度
"""
# 读取图片
img1 = Image.open(img1_path)
img2 = Image.open(img2_path)
# 计算汉明距离
distance = bin(phash(img1) ^ phash(img2)).count('1')
similary = 1 - distance / max(len(bin(phash(img1))), len(bin(phash(img1))))
return similary
# 直方图计算图片相似度算法
def make_regalur_image(img, size=(256, 256)):
"""我们有必要把所有的图片都统一到特别的规格,在这里我选择是的256x256的分辨率。"""
return img.resize(size).convert('RGB')
def hist_similar(lh, rh):
assert len(lh) == len(rh)
return sum(1 - (0 if l == r else float(abs(l - r)) / max(l, r)) for l, r in zip(lh, rh)) / len(lh)
def calc_similar(li, ri):
return sum(hist_similar(l.histogram(), r.histogram()) for l, r in zip(split_image(li), split_image(ri))) / 16.0
def calc_similar_by_path(lf, rf):
li, ri = make_regalur_image(Image.open(lf)), make_regalur_image(Image.open(rf))
return calc_similar(li, ri)
def split_image(img, part_size=(64, 64)):
w, h = img.size
pw, ph = part_size
assert w % pw == h % ph == 0
return [img.crop((i, j, i + pw, j + ph)).copy() for i in range(0, w, pw) \
for j in range(0, h, ph)]
五、结果
来源:https://blog.csdn.net/weixin_43723625/article/details/117298412
0
投稿
猜你喜欢
- 需求桌面临时文件较多时,直接删了不太放心,不删又显得很杂乱,故需要写一个脚本批量清理并备份这些鸡肋的文件。所以脚本需要具有以下功能1. 可以
- 前几天看到某论坛有人提了这么个问题,Python这么火,为啥找工作这么难呢? 这两年因为第三波人工智能热潮让 Python火了一把
- 在实际数据分析过程中,我们分析用Python来处理数据(海量的数据),我们都是把这个数据转换为Python的对象的,比如最为常见的字典。比如
- 一、多线程同步由于CPython的python解释器在单线程模式下执行,所以导致python的多线程在很多的时候并不能很好地发挥多核cpu的
- 前言最近遇到一个mysql在RR级别下的死锁问题,感觉有点意思,研究了一下,做个记录。涉及知识点:共享锁、排他锁、意向锁、间隙锁、插入意向锁
- CategoricalDtype自定义排序当我们的透视表生成完毕后,有很多情况下需要我们对某列或某行值进行排序。排序有很多种方法。例如sor
- 作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。Go 语言中变量可以在三个地方声明:函数内定义的变量称为局部变量
- 前言大家谈及用Pandas导出数据,应该就会想到to.xxx系列的函数。这其中呢,比较常用的就是pd.to_csv()和pd.to_exce
- nii.gz格式是医学图像常用的压缩格式,python中可用nibabel和sitk来读取保存。使用nibabel由于使用nibabel图像
- canny边缘检测原理canny边缘检测共有5部分组成,下边我会分别来介绍。1 高斯模糊(略)2 计算梯度幅值和方向。可选用的模板:sobl
- ImageFont模块定义了相同名称的类,即ImageFont类。这个类的实例存储bitmap字体,用于ImageDraw类的text()方
- 导读我们在使用selenium打开google浏览器的时候,默认打开的是一个新的浏览器窗口,而且里面不带有任何的浏览器缓存信息。当我们想要爬
- 前言:这个先来创建一个模块,名称为christmastree,在该模块中,首先定义一个全局变量,然后创建一个名称为fun_christmas
- 本文实例讲述了python实现class对象转换成json字典的方法。分享给大家供大家参考,具体如下:# -*- encoding: UTF
- 前言:我们常常想使用数组的方法,比如forEach,filter,又或者some等等来处理非数组的数据类型,那么在这些场景下,我们就需要将非
- 前言手里有一点点公司的股票, 拿不准在什么时机抛售, 程序员也没时间天天盯着看,不如动手写个小程序, 把股票趋势每天早上发到邮箱里,用 py
- 全局变量是魔鬼。在YUI中,我们仅用两个全局变量:YAHOO和YAHOO_config。YUI的一切都是使用YAHOO对象级的成员或这个成员
- 本文实例讲述了JS实现带鼠标效果的头像及文章列表代码。分享给大家供大家参考。具体如下:这是一种带图片功能的文章或新闻列表功能,鼠标滑过标题列
- 前言:最近正在将一个使用单文件组件的 Options API 的 Vue2 JavaScript 项目升级为 Vue3 typescript
- 最近跑实验,遇到了一个问题:由于实验数据集比较多,每次跑完一个数据集就需要手动更改文件路径,再将文件传到服务器,再运行实验,这样的话效率很低