蠡測 2022-07-13 15:15 采纳率: 57.1%
浏览 44
已结题

opencv 以图识图

问题遇到的现象和发生背景

想问如何建立book.csv
现在可以正常运行 就是无法识别
如何更改可以达到识别功能
代码来自https://blog.csdn.net/cliukai/article/details/102467502

问题相关代码,请勿粘贴截图
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):
        # 创建results字典
        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)
            # 把score存入字典,字典的键固定为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 = r"C:\opencv\source"
# 待查询照片的路径
queryPath = r"C:\opencv\search\search1.jpg"


# 书本数据库,里面保存了照片-作者-书名
bookDatabasePath = "books.csv"
# 新建一个保存封面的字典
bookDatabase = {}
# 把csv里面的数据放入字典,字典的键就是照片名,值就是作者,书名信息
for book in csv.reader(open(bookDatabasePath)):
    # book 读出来是“书名,作者,其他等信息”
    bookDatabase[book[0]] = book[1:]

# 初始化封面描述和封面匹配对象
# 封面描述需要指定描述方法
cd = CoverDescriptor()
# 封面匹配需要指定距离度量方法,例如Hamming
cm = CoverMatcher(cd, glob.glob(coverPath + "*.jpg"), 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)
# print(cd.describe(gray))
print(bookDatabase)
# 显示出待查询的封面
cv2.imshow("query", queryImage)

# 如果在数据库里没有找到书的封面
if len(results) == 0:
    print("没有找到")
    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()

运行结果及报错内容
我的解答思路和尝试过的方法
我想要达到的结果
  • 写回答

1条回答 默认 最新

  • 脚踏南山 2022-07-13 15:34
    关注

    如有帮助,敬请采纳,你的采纳是我前进的动力,O(∩_∩)O谢谢!!!!!!!!

    import csv
    
    
    def test_03_writer_csv():
        # 写csv数据
        with open('books.csv', 'w+', encoding='utf-8-sig', newline='') as csf:
            writer = csv.writer(csf)
            write_data = ['照片', '作者', '书名']
            writer.writerow(write_data)
            data_list = [
                ['img_1', '王五', '王五的医生'],
                ['img_2', '王1五1', '王1五的医生'],
                ['img_3', '王2五', '王2五的医生']]
            for data in data_list:
                writer.writerow(data)
    
    test_03_writer_csv()
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 7月22日
  • 已采纳回答 7月14日
  • 创建了问题 7月13日

悬赏问题

  • ¥15 evo评估时曲线出现问题
  • ¥15 eNSP拓扑图配置实验
  • ¥20 有没有兄弟会替换fmod studio的.bank文件内的音效?
  • ¥20 如何解决访问网址被屏蔽的情况
  • ¥15 本地运行的vue2项目,使用内网穿透,前端界面一直转圈圈
  • ¥20 powerbuilder datawindow控件导出Excel数据,可不可以不自动覆盖原数据,而是在后面新插入入数据。
  • ¥100 无轴承永磁同步电机控制
  • ¥15 eps里添加本地倾斜模型
  • ¥15 telegram 问题
  • ¥15 nrf52810-c三个a 程序