使用OpenCV-python实现以图搜图

opencv实现以图搜图 opencv 实现以图搜图 阅读详情

使用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 = descriptor
        self.coverPaths = coverPaths
        self.ratio = ratio
        self.minMatches = minMatches
        self.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] = score
        if len(results) > 0:
            results = sorted([(v, k) for (k, v) in results.items() if v > 0],
                reverse = True)
        return results
	
    # 输入为两张图的keypoints和feature vectors
    def match(self, kpsA, featuresA, kpsB, featuresB):
        # 新建一个描述匹配的对象,距离的度量方法是BruteForce-Hamming
        matcher = cv2.DescriptorMatcher_create(self.distanceMethod)
        # 对两幅图片的特征描述做knn近邻匹配
        # 2表示对每个特征向量寻找和他最近的2个邻居
        # 返回的并不是实际映射的关键点mapping keypoints
        rawMatches = 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 cv2

class 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 = descriptor
        self.coverPaths = coverPaths
        self.ratio = ratio
        self.minMatches = minMatches
        self.distanceMethod = "BruteForce"
        if useHamming:
            self.distanceMethod += "-Hamming"

    def search(self, queryKps, queryDescs):
        # initialize the dictionary of results
        results = {}

        # loop over the book cover images
        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] = score

        # if matches were found, sort them
        if len(results) > 0:
            results = sorted([(v, k) for (k, v) in results.items() if v > 0],
                reverse = True)
        return results

    def match(self, kpsA, featuresA, kpsB, featuresB):
        # 新建一个描述匹配的对象,方法是BruteForce-Hamming
        matcher = 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 process
        if len(matches) > self.minMatches:
            # construct the two sets of points
            ptsA = 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 keypoints
            return float(status.sum()) / status.size

        # no matches were found
        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()        
python实现以图找图findpic(以寻找一个图像在另一个图像中的位置) 【代码】python实现以图找图findpic(以寻找一个图像在另一个图像中的位置) 阅读详情

相关推荐

chatgpt赋能python:Python以图搜图:如何用Python优化SEO?

本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的ChatGPT,应该选择拥抱而不是抗拒,未来属于“会用”AI的人。🧡AI职场汇报智能办公文案写作效率提升教程 🧡专注于AI+职场+办公方向。下图是课程的整体大纲下图是AI职场汇报智能办公文案写作效率提升教程中用到的ai工具。

weixin_45566993的博客 540

OpenCV(图像处理)-图片搜索

openCV图片搜索

羊羊羊 4339

python 以图搜图百度_基于opencv的图片检索(模仿百度的以图搜图功能)

曾经有一篇文章简单的介绍了CBIR(Content-Based Image Retrieval),详细内容猛戳基于内容的图像检索技(CBIR)术相术介绍。CBIR由于其应用的广泛性,特别是近年来,随着数码设备的迅猛普及,网络上的图片每天以几十亿级的速度猛增,而且对于一些摄影爱好者和自拍族来说,电脑和存储设备里更是有数不清的图片,如何从这么多图片中找到自己所需的图片是困惑很多人的难题。而CBIR正是...

weixin_35799294的博客 1833

图像检索(以图搜图)python实现

算法思想:统计每个特征(对应词典–也就是聚类的1800个特征中心)在训练集中出现的次数(比如一个特征在15张图片中存在,则该特征对应的值为15),得到一个1800长度的一维向量。算法:提取搜索图片的sift特征,结合之前获取到的词典得到BOF特征向量,计算训练集中每张图片的BOF向量和该特征向量的余弦相似度(越相似,值越小),得到最终的排序结果。函数说明:输入搜索图片的路径,返回最相似的15张图片(由于作者采用的训练集包括了测试集图片,所以查询16张,将查询到的最相似的一张图片(其本身)排除)

weixin_47696370的博客 1万+

使用OpenCV实现以图搜图

使用OpenCV实现以图搜图

summerriver1的博客 2733

python 以图搜图

import os import cv2 as cv import numpy as np import pandas as pd import matplotlib.pyplot as plt #读取文件 def read_img(): imgs = [] # walk会返回3个参数,分别是路径,目录list,文件list for path, lists, frame...

Como0413的博客 5713

用Python实现以图搜图系统:基于OpenCV的感知哈希实战指南

本文详细介绍了如何使用Python和OpenCV构建高效的以图搜图系统,重点讲解感知哈希(pHash)算法在图像相似性计算中的应用。通过环境配置、图像预处理、哈希生成到高效检索系统的实现,帮助开发者快速掌握百万级图库搜索技术,并提供了性能优化和API封装的最佳实践。

z5a6b的博客 877

使用 MobileNet和ImageHash做图片相似度匹配(以图搜图)

使用MobileNet 和图片哈希提取图片特征值比对相似相;MobileNet还可以用于图片分类;

robinfoxnan的专栏 2984

python使用opencv_使用OpenCV-python实现以图搜图

import numpy as npimport globimport csvimport cv2class CoverDescriptor:def describe(self, image):descriptor = cv2.BRISK_create()(kps, descs) = descriptor.detectAndCompute(image, None)kps = np.float32(...

weixin_39703982的博客 523

使用python和opencv实现相机标定

相机标定确定了相机的内部和外部参数,包括焦距、畸变等,使得像素坐标能够准确映射到世界坐标或相反。这为位姿估计提供了基础,通过相机标定获得的参数,可以在计算机视觉中精确地定位物体、重建场景,实现位姿估计并在增强现实、三维重建等领域中应用。

一只AI小白 3912

Python实现图像搜索

假设我们有一个存储了若干图片的数据库,现在我们输入一张图片,需要在数据库中找到与之最相似的图片。我们首先需要将输入的图片进行哈希计算,然后依次与数据库中的每张图片进行相似度计算,最后返回相似度小于等于5的图片。代码中的dhash函数用来计算一张图片的哈希值,hamming_distance函数用来计算两个哈希值之间的汉明距离,get_similar_images函数用来获取相似的图片。图像搜索是一种常见的应用场景,它可以通过输入一张图片,在存储的图片库中找出与之相似的图片。Python实现图像搜索。

持续更新 1365

OpenCV学习笔记22. 以图搜图,感知Hash的原理与实现(python/c++)

以图搜图,感知Hash的原理与实现 以下内容引自百度百科: 感知哈希算法(Perceptual hash algorithm)是哈希算法的一类,主要用来做相似图片的搜索工作。图片所包含的特征被用来生成一组指纹(不过它不是唯一的), 而这些指纹是可以进行比较的。 概括地讲,感知哈希算法一共分两步: 1、把图片转化为字符串 ,这个字符串就是图片的hash值,又称指纹 2、求两个字符串

两鬓已不能斑白的专栏 6101

基于Python+OpenCV+PyQt5的以图搜图系统课程设计全解析

图像检索是计算机视觉中的基础应用,核心目标是从图像库中找到与查询图像视觉相似的图片。实现这一功能通常需要依次完成图像特征提取、特征向量表示与相似度度量三个关键步骤。其中,颜色直方图因计算简单、对旋转和尺度变化不敏感,成为入门级检索系统的常用特征。开发者可借助Python生态快速搭建完整应用:使用OpenCV进行图像读取、颜色空间转换与直方图计算,利用PyQt5构建桌面交互界面,实现从选择图片到展示排序结果的完整链路。此类项目在课程设计、原型验证和实验演示中均有广泛应用。本文以颜色直方图特征为例,系统讲解了环

weixin_30740295的博客 338

零基础实现第一个以图搜图应用

作为新手,我也尝试用Python和OpenCV做了一个最简单的版本,发现其实没有想象的那么难。OpenCV提供了计算颜色直方图的功能,这是最简单有效的特征提取方法。测试发现,对于颜色特征明显的图片,搜索效果相当不错。当然,这个方法也有局限,对形状和纹理的识别能力较弱。用OpenCV提供的现成函数,配合Python简洁的语法,很快就能看到成果。如果想进一步提升效果,可以尝试更高级的特征提取方法,比如SIFT、SURF等局部特征。实际操作中发现,从代码编写到看到结果的过程非常流畅,确实降低了入门门槛。

JetRaven12的博客 738

opencv以图搜图

使用opencv2.4.9 使用VS2013 基于图像直方图颜色空间比较

Unity UI Toolkit避坑指南:从官方Samples到实际项目,这些‘坑’我帮你踩过了

本文分享了Unity UI Toolkit在实际项目中的避坑经验和优化技巧,包括动画系统的高效替代方案、3D世界UI的创新实现方式、USS样式继承的反直觉规则等。通过详细的代码示例和性能优化策略,帮助开发者避免常见陷阱,提升开发效率。

weixin_29535577的博客 342

OpenCV实战:5分钟搞定图片相似度匹配(Python版)

本文介绍如何使用Python和OpenCV在5分钟内实现高效的图片相似度匹配,特别适合构建以图搜图系统。通过ORB算法提取特征、暴力匹配器计算相似度,并提供优化技巧和实际应用案例,帮助开发者快速掌握这一实用技术。

weixin_29021291的博客 225

手把手实战:RK3588上YOLOv8模型从训练到部署全流程解析

本文详细解析了在RK3588开发板上部署YOLOv8目标检测模型的全流程。从模型训练、正确导出适配的ONNX格式,到使用RKNN-Toolkit2进行模型转换与量化,最后在板卡上完成部署与性能测试。文章提供了完整的代码示例和关键避坑指南,帮助开发者高效实现嵌入式AI应用落地。

weixin_28224217的博客 404

python的opencv使用总结

巴拉巴拉

jack的博客 7456

汉字跨越三千年的生命力与数字时代适应性

文字作为文明载体,其演变规律始终遵循实用性与适应性的平衡。汉字作为现存最古老的文字系统,凭借形义结合的六书构造原理,实现了超方言的文化统一功能。在计算机处理方面,五笔输入法与Unicode支持证明了其技术兼容性,而视觉识别效率的先天优势使其在信息时代更具传播效力。从甲骨文识别AI到现代书法设计,汉字系统持续展现强大的文化承载力与技术适应性,这种活态传承为数字人文研究提供了独特样本。

weixin_29058331的博客 353

PLC控制气缸与电磁阀:从原理到实战编程详解

在工业自动化领域,很多工程师都能编写PLC程序控制电机启停,但当涉及到气缸和电磁阀的精确控制时,却常常遇到动作不协调、响应延迟甚至设备损坏的问题。这背后的关键不在于PLC编程本身,而在于对气动元件特性和控制逻辑的深入理解。 本文将从实际工程问题出发,深入解析气缸与电磁阀的工作原理、PLC控制逻辑设计、常见故障排查方法,并通过完整的梯形图实例,帮助读者掌握气动系统自动化编程的核心要点。无论你是刚接触PLC的初学者,还是希望提升气动控制技能的工程师,都能从中获得实用的技术指导。 1. 气缸与电磁阀在自动化控制中

weixin_42522374的博客 337

使用python opencv实现瞳孔追踪

使用python+Opencv实现瞳孔识别与跟踪 使用opencv做瞳孔识别是十分方便的,它有很多好用的库可以直接使用。 废话不多说,直接上代码。 下面展示一些 内联代码片。 // A code block var foo = 'bar'; import cv2 import numpy as np cap = cv2.VideoCapture("eyes.mp4") while (True): ret, frame = cap.read() if ret is False:

HC_wood的博客 8814

思科9117AP从零配置EWC模式实战:Wi-Fi6网络搭建避坑指南

本文详细介绍了思科9117AP在Wi-Fi6网络环境下配置EWC模式的实战指南,涵盖镜像准备、网络环境配置、模式转换步骤及高级运维技巧。通过EWC模式,企业可实现控制器与AP的一体化部署,显著降低成本和简化运维,特别适合中小企业Wi-Fi6网络搭建。

weixin_28318011的博客 332
上一篇: Python链表学习
下一篇: 图像金字塔:高斯金字塔vs拉普拉斯金字塔
刘凯KAI
博客等级 码龄15年 663粉丝 128原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值