使用OpenCV-python实现以图搜图,首先加载必要的库

import numpy as np
import glob
import csv
import cv2

使用BRISK方法描述图片的特征

建立封面描述,计算特征点和特征点周围的信息

class CoverDescriptor:def describe(self, image):# 使用BRISK方法对图片进行特征提取,同类型的还有SIFT,SURF等等descriptor = cv2.BRISK_create()# 第一步是detect找到特征点,特征点信息包括关键点的位置,大小,旋转角等等# 第二步是计算特征点周围的特征描述子,None表示没有遮罩(kps, descs) = descriptor.detectAndCompute(image, None)# 这里的keypoint只需要坐标位置就可以了,丢弃其他性质kps = np.float32([kp.pt for kp in kps])# 返回ROI点和对应周围的环境描述子return (kps, descs)

使用KNN和RANSAC方法对特征进行匹配

建立匹配描述

class CoverMatcher:# 2个必须输入分别为:待查找照片的描述对象,所有封面所在的文件夹位置# ratio是计算单应矩阵最邻近举例的比例# BRISK算法产生的是二值特征向量binary feature vectors,不能用欧拉距离衡量,需要使用Hamming方法# 当然对应的SIFT产生的是实值特征向量real-valued feature vectors,可以用欧拉距离度量def __init__(self, descriptor, coverPaths, ratio = 0.7, minMatches = 40,useHamming = True):self.descriptor = descriptorself.coverPaths = coverPathsself.ratio = ratioself.minMatches = minMatchesself.distanceMethod = "BruteForce"if useHamming:self.distanceMethod += "-Hamming"def search(self, queryKps, queryDescs):results = {}for coverPath in self.coverPaths:cover = cv2.imread(coverPath)gray = cv2.cvtColor(cover, cv2.COLOR_BGR2GRAY)(kps, descs) = self.descriptor.describe(gray)# query是待查图片的特征信息,后面的是当前数据库里每一张图片的信息score = self.match(queryKps, queryDescs, kps, descs)# 把分数存入字典,字典的键固定为50个,值为对应的匹配分results[coverPath] = scoreif len(results) > 0:results = sorted([(v, k) for (k, v) in results.items() if v > 0],reverse = True)return results# 输入为两张图的keypoints和feature vectorsdef match(self, kpsA, featuresA, kpsB, featuresB):# 新建一个描述匹配的对象,距离的度量方法是BruteForce-Hammingmatcher = cv2.DescriptorMatcher_create(self.distanceMethod)# 对两幅图片的特征描述做knn近邻匹配# 2表示对每个特征向量寻找和他最近的2个邻居# 返回的并不是实际映射的关键点mapping keypointsrawMatches = matcher.knnMatch(featuresB, featuresA, 2)matches = []for m in rawMatches:# 首先确保是2个匹配matches# 然后确保第1个match的距离<0.7*第2个match的距离,从而减少计算量if len(m) == 2 and m[0].distance < m[1].distance * self.ratio:matches.append((m[0].trainIdx, m[0].queryIdx))# 确保有足够多的匹配点if len(matches) > self.minMatches:# 保存匹配点的(x,y)坐标ptsA = np.float32([kpsA[i] for (i, _) in matches])ptsB = np.float32([kpsB[j] for (_, j) in matches])# RANSAC表示 Random Sample Consensus随机样本一致性,是一种迭代方法# 这里也可以用cv2.LMEDS方法 Least-Median robust# 4.0表示ptsA和ptsB之间的误差# 返回值为变换矩阵和一系列布尔量的列表,1表示匹配,0表示不匹配(_, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, 4.0)# status是一个list,里面都是[1,0,1,0,0,1],使用sum()求和,使用size求长度# 返回的是匹配的比率return float(status.sum()) / status.size# 如果没有返回匹配比率,说明没有匹配到,函数报错结束return -1.0

在数据库中实现以图搜图

# 封面图片的路径
coverPath = "covers"
# 待查询照片的路径
queryPath = "queries/query01.png"
queryPath = "queries/query02.png"
queryPath = "queries/query03.png"
queryPath = "queries/query04.png"
# queryPath = "queries/query05.png"# 书本数据库,里面保存了照片-作者-书名
bookDatabasePath = "books.csv"
# 新建一个保存封面的字典
bookDatabase = {}
# 把csv里面的数据放入字典,字典的键就是照片名,值就是作者,书名信息
for book in csv.reader(open(bookDatabasePath)):# book 读出来是“书名,作者,其他等信息”bookDatabase[book[0]] = book[1:]# 初始化封面描述和封面匹配对象
# 封面描述需要指定描述方法,例如SIFT
cd = CoverDescriptor()
# 封面匹配需要指定距离度量方法,例如Hamming
cm = CoverMatcher(cd, glob.glob(coverPath+"/*.png"),ratio=0.7,minMatches=40)# 加载查询图像
queryImage = cv2.imread(queryPath)
# 降噪,转换成灰度图
gray = cv2.cvtColor(queryImage, cv2.COLOR_BGR2GRAY)
# 提取关键点和描述子
(queryKps, queryDescs) = cd.describe(gray)# 注意这个cm是CoverMatcher,search是CoverMatcher里面的一个方法
# 在已有的数据库中进行匹配,返回匹配分数和匹配对象的路径,注意这里的路径表达里面有个转义字符
# 举例,某一个返回值是[(0.9871794871794872, 'covers\\cover016.png')]
results = cm.search(queryKps, queryDescs)# 显示出待查询的封面
cv2.imshow("query",queryImage)# 如果在数据库里没有找到书的封面
if len(results)==0:print("cannot find a match for that cover in databse!")cv2.waitKey(0)
else:# results的格式是[(0.9871794871794872, 'covers\\cover016.png')]for i,(score,coverPath) in enumerate(results):# rfind和find不同,rfind找出最右边的字符# 在字典中查询coverPath对应的值,首先需要提取'covers\\cover016.png'中的'cover016.png',注意这里需要使用转义反斜杠# 也可以这样使用coverPath.split('||')[-1](author,title) = bookDatabase[coverPath[coverPath.rfind("\\")+1:]]# (author,title) = bookDatabase[coverPath.split("\\")[-1]]# 打印输出结果,百分比保留2位小数点print("loop{} precision is {:.2f}%: author is {} - title is {}".format(i+1,score*100,author,title))# 这个coverPath是对应数据库文件里的图片result = cv2.imread(coverPath)cv2.imshow("results",result)cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果首先显示精确度和对应的作者和书名

loop1 precision is 68.42%: author is Michael Crichton - title is State of Fear

然后显示被查找的图片,和数据库里面对应的照片

完整代码和附录

import numpy as np
import glob
import csv
import cv2class CoverDescriptor:def describe(self, image):descriptor = cv2.BRISK_create()(kps, descs) = descriptor.detectAndCompute(image, None)kps = np.float32([kp.pt for kp in kps])return (kps, descs)class CoverMatcher:def __init__(self, descriptor, coverPaths, ratio = 0.7, minMatches = 40,useHamming = True):self.descriptor = descriptorself.coverPaths = coverPathsself.ratio = ratioself.minMatches = minMatchesself.distanceMethod = "BruteForce"if useHamming:self.distanceMethod += "-Hamming"def search(self, queryKps, queryDescs):# initialize the dictionary of resultsresults = {}# loop over the book cover imagesfor coverPath in self.coverPaths:cover = cv2.imread(coverPath)gray = cv2.cvtColor(cover, cv2.COLOR_BGR2GRAY)(kps, descs) = self.descriptor.describe(gray)# query是待查图片的特征信息,后面的是当前数据库里每一张图片的信息score = self.match(queryKps, queryDescs, kps, descs)# 把分数存入字典,字典的键固定为50个,值为对应的匹配分results[coverPath] = score# if matches were found, sort themif len(results) > 0:results = sorted([(v, k) for (k, v) in results.items() if v > 0],reverse = True)return resultsdef match(self, kpsA, featuresA, kpsB, featuresB):# 新建一个描述匹配的对象,方法是BruteForce-Hammingmatcher = cv2.DescriptorMatcher_create(self.distanceMethod)# 对两幅图片的特征描述做knn近邻匹配rawMatches = matcher.knnMatch(featuresB, featuresA, 2)matches = []for m in rawMatches:if len(m) == 2 and m[0].distance < m[1].distance * self.ratio:matches.append((m[0].trainIdx, m[0].queryIdx))# check to see if there are enough matches to processif len(matches) > self.minMatches:# construct the two sets of pointsptsA = np.float32([kpsA[i] for (i, _) in matches])ptsB = np.float32([kpsB[j] for (_, j) in matches])# compute the homography between the two sets of points# and compute the ratio of matched points(_, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, 4.0)# return the ratio of the number of matched keypoints# to the total number of keypointsreturn float(status.sum()) / status.size# no matches were foundreturn -1.0        # 封面图片的路径
coverPath = "covers"
# 待查询照片的路径
queryPath = "queries/query01.png"
queryPath = "queries/query02.png"
queryPath = "queries/query03.png"
queryPath = "queries/query04.png"
# queryPath = "queries/query05.png"# 书本数据库,里面保存了照片-作者-书名
bookDatabasePath = "books.csv"
# 新建一个保存封面的字典
bookDatabase = {}
# 把csv里面的数据放入字典,字典的键就是照片名,值就是作者,书名信息
for book in csv.reader(open(bookDatabasePath)):# book 读出来是“书名,作者,其他等信息”bookDatabase[book[0]] = book[1:]# 初始化封面描述和封面匹配对象
# 封面描述需要指定描述方法,例如SIFT
cd = CoverDescriptor()
# 封面匹配需要指定距离度量方法,例如Hamming
cm = CoverMatcher(cd, glob.glob(coverPath+"/*.png"),ratio=0.7,minMatches=40)# 加载查询图像
queryImage = cv2.imread(queryPath)
# 降噪,转换成灰度图
gray = cv2.cvtColor(queryImage, cv2.COLOR_BGR2GRAY)
# 提取关键点和描述子
(queryKps, queryDescs) = cd.describe(gray)# 注意这个cm是CoverMatcher,search是CoverMatcher里面的一个方法
# 在已有的数据库中进行匹配,返回匹配分数和匹配对象的路径,注意这里的路径表达里面有个转义字符
# 举例,某一个返回值是[(0.9871794871794872, 'covers\\cover016.png')]
results = cm.search(queryKps, queryDescs)# 显示出待查询的封面
cv2.imshow("query",queryImage)# 如果在数据库里没有找到书的封面
if len(results)==0:print("cannot find a match for that cover in databse!")cv2.waitKey(0)
else:# results的格式是[(0.9871794871794872, 'covers\\cover016.png')]for i,(score,coverPath) in enumerate(results):# rfind和find不同,rfind找出最右边的字符# 在字典中查询coverPath对应的值,首先需要提取'covers\\cover016.png'中的'cover016.png',注意这里需要使用转义反斜杠# 也可以这样使用coverPath.split('||')[-1](author,title) = bookDatabase[coverPath[coverPath.rfind("\\")+1:]]# (author,title) = bookDatabase[coverPath.split("\\")[-1]]# 打印输出结果,百分比保留2位小数点print("loop{} precision is {:.2f}%: author is {} - title is {}".format(i+1,score*100,author,title))# 这个coverPath是对应数据库文件里的图片result = cv2.imread(coverPath)cv2.imshow("results",result)cv2.waitKey(0)
cv2.destroyAllWindows()

使用OpenCV-python实现以图搜图相关推荐

  1. python tensorflow 以图搜图_GitHub - lomoss/SearchImage: 基于VGG16的图像检索系统,简单的以图搜图。...

    项目介绍: 一个简单以图搜图的demo项目,采用vgg16提取特征值,使用Miluvs向量搜索引擎,只有简单几个文件,没有什么技术含量. 项目目录: -SearchImage#项目 -app#Flas ...

  2. 以图搜图Python实现Hash算法

    以图搜图(一):Python实现dHash算法 http://yshblog.com/blog/43 以图搜图(二):Python实现pHash算法 http://yshblog.com/blog/4 ...

  3. 以图搜图(一):python aHash算法

    文章目录 感知哈希算法 实现过程 python代码 缺点 感知哈希算法 以图搜图的关键技术叫做"感知哈希算法"(Perceptual hash algorithm),它的作用是对每 ...

  4. python以图搜图_以图搜图(一):Python实现dHash算法(转)

    近期研究了一下以图搜图这个炫酷的东西.百度和谷歌都有提供以图搜图的功能,有兴趣可以找一下.当然,不是很深入.深入的话,得运用到深度学习这货.Python深度学习当然不在话下. 这个功能最核心的东西就是 ...

  5. python+milvus实现一个以图搜图系统

    目录 引言 说明 准备数据 训练数据 安装minlvus(docker-compose方式) python集成milvus+towhee python后端启动方式 启动前端 查询数据 引言 当您听到& ...

  6. 【python 以图搜图】三种图片相似度计算融合算法

    目标:在一个文件夹找出相似度较高的图片,达到以图搜图的目的. 我找了十组,都是高度相似的图片. 核心算法: 1.分别自定义三种计算图片相似度算法,计算图片相似度算法ORB算法,以及局部敏感哈希phas ...

  7. 以图搜图算法pytorch,Python以图搜图爬虫

    python可以用图搜图吗 谷歌人工智能写作项目:小发猫 百度图片搜索引擎原理是如何实现的 图片搜索的原理有三个步骤1. 将目标图片进行特征提取,描述图像的算法很多,用的比较多的是:SIFT描述子,指 ...

  8. 实战 | 多种方法实现以图搜图

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:AI 算法与图像处理 概述 以图搜图技术是日常生活中常用 ...

  9. 7 招教你轻松搭建以图搜图系统!

    作者 | 小龙 责编 | 胡巍巍 当您听到"以图搜图"时,是否首先想到了百度.Google 等搜索引擎的以图搜图功能呢?事实上,您完全可以搭建一个属于自己的以图搜图系统:自己建立图 ...

  10. 图像匹配,基于深度学习DenseNet实现以图搜图功能

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx 度学习的发展使得在此之前以机器学习为主流算法的相关实现变得简单,而且准确率更高,效果更好,在图 ...

最新文章

  1. mysql 运行sql 编码_关于解决运行 sql 文件时, 找不到 MySQL 默认编码 utf8mb4 的问题...
  2. 搜索引擎的两大问题(2) - 相关性
  3. csharp DataTable and DataGridView delete a Row
  4. 26 | 案例篇:如何找出狂打日志的“内鬼”?
  5. mysql备份、导入、远程数据库设置
  6. 数据源(连接池)的作用
  7. 使用ABAP代码获得Netweaver环境变量
  8. 云有约 | 精华汇总
  9. java entitymanager类_如何在Java JDBC EntityManagerFactory类中设置实体的ID?
  10. 作者:吴东亚(1972-),女,中国电子技术标准化研究院信息技术研究中心高级工程师、副主任,国家OID注册中心副主任。...
  11. 超键、候选键、主键、外键区别?
  12. ENVI学习总结(八)——图像镶嵌
  13. 使用Gson 解析json文件
  14. matlab中mapminmax()函数的用法
  15. Java求某一天是星期几
  16. 配置java win10_win10 Java14安装及配置
  17. svc预测概率_Kaggle平台Titanic生存率预测项目(TOP3%)
  18. MQTT跨ip/跨机访问
  19. 【自动化测试】Web自动化测试框架01
  20. jQuery实现倒计时计时器

热门文章

  1. 新手小白,做短视频自媒体创业,需要准备什么?
  2. 二战 北航 浙大 计算机,二战北航,成功上岸,分享经验给大家
  3. 回合制小游戏(英文)
  4. 在VMware8.0下安装crux2.6
  5. 卷积神经网络(CNN)在语音识别中的应用
  6. skywalking安装
  7. STC8H8K64U单片机-看门狗配置与讲解
  8. 腾讯汤道生:产业互联网开放生态已初步形成,2021加大SaaS生态建设|CEO说
  9. 下载频道--IT资源关东煮第三期
  10. 神舟炫龙银魂t1是哪年的_我的天呐 对比发现炫龙银魂T1竟然这么强