作者:昼夜
关键词:图搜图,特征提取
在很多的工作场景当中,为了集体工作的方便都会运用到共享文件夹,大家都会把各类文件上传到这个文件夹中,当某个员工要使用的时候就可以直接去检索。比如,运营同学需要找几张产品图片去上架的时候,可以直接在共享文件夹中根据已有图片去查找获取,但是随着持续的运营发展,当文件夹中保存了大量的图片文件的时候,人工审查检索需要花费大量的时间,那么我们如何通过一张图片来检索到类似图片呢,我们可以通过以下集中方法来实现。
1.图片特征提取对比
在该方法中,我们通过ORB特征检测方法,通过比较像素点的亮度来检索图像中的关键点,以此找到图像角点。然后,会根据图像梯度为每个关键点分配一个方向,并用随机测试来生成描述符,最后通过计算各个描述符之间的汉明距离进行特征点的匹配,得到两张图片的相似度,可以较快的实现两张图片之间的比较。虽然说整体逻辑较为复杂,但是好在ORB特征检测这个方法已经被大牛封装好了,我们只需要调用即可,来看一下具体的代码实现逻辑。
1.设定阈值,用来筛选匹配的特征点
2.读取传入的两张要比较的图片信息
3.创建ORB 特征提取器,提取两张图片的关键点和描述符
4.以汉明距离作为相似度度量,创建一个匹配规则
5.使用匹配规则对两张图片进行匹配,可以选择每个描述符返回几个最佳匹配(一般使用到的是2个,最近与次近)
6.遍历匹配对,如果符合则将该匹配点加入到列表中(对应的规则为最近邻匹配的距离小于rank(0.7)乘以次近邻匹配的距离)
7.返回符合相似度阈值的匹配点的数量,即列表的长度,长度越大说明相似度越高,两张图片越符合
import cv2
def similarity_calculate_ORB(pic_path, compare_path):
rank = 0.7 # 阈值
# 读取图片
img1 = cv2.imread(pic_path)
img2 = cv2.imread(compare_path)
# --提取图片的特征进行匹配--
# 创建特征提取器和匹配器
orb = cv2.ORB_create()
# 提取关键点和描述符
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)
# 匹配描述符
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=False)
matches = bf.knnMatch(des1,des2,k=2)
good_matches = []
for m, n in matches:
if m.distance < rank * n.distance:
good_matches.append([m])
# 输出匹配结果
return len(good_matches)在影刀中实现整体功能的逻辑:
1.将要查找的图片都放在同一个文件夹pic01下,外循环循环整个文件夹中的文件,实现所有目标图片的相似图查找
2.内循环去循环共享文件夹下的所有图片,调用函数去进行两两匹配,最终记录相似度最高的图片
3.在pic01内创建目标图片同名文件夹,将找到的相似图片放入这个文件夹内完成搜索

2.通过百度云付费产品实现
具体功能已有介绍,可以参考如下文档:
https://www.yingdao.com/community/detaildiscuss?id=5473f071-392e-4491-ba06-1ee867f798ca
这边我们在test_pic01文件夹中放入需要查找的两张图片,在test_pic_group01文件夹中放入一些用来比较的图片,以此来进行场景的模拟。

当然,我们也可以在影刀中设定一个权重线,如果相似质量超过这个线的数值则进行记录,来实现多个相似图片查找的功能。
1.在使用的时候注意需要将磁盘空间预留出1G左右的空间,防止有些图片像素点过多引发的报错
2.可以根据实际业务的需求去改变阈值,依次来实现更多或更精确的图片搜索