opencv - ORB+BFMatcher 是否适合识别重复图像(有细微的变化?)
问题描述
我需要识别具有已知值的手写数字的图像。带有数字的物理对象始终相同,但位置/比例/照明略有不同。它们的数量约为 100,大小约为 100x500 像素。
在第一遍中,代码应该“学习”可能的输入,然后在它们再次出现时识别它们(将它们分类为接近“训练”图像之一)。
我主要关注的是特征匹配 Python-OpenCV 教程
首先分析输入图像,在orbTrained
列表中记住关键点和描述符:
import cv2
import collections
ORBTrained=collections.namedtuple('ORBTrained',['kp','des','img'])
orbTrained=[]
for img in trainingImgs:
z2=preprocessImg(img)
orb=cv2.ORB_create(nfeatures=400,patchSize=30,edgeThreshold=0)
kp,des=orb.detectAndCompute(z2,None)
orbTrained.append(ORBTrained(kp=kp,des=des,img=z2))
z3=cv2.drawKeypoints(z2,kp,None,color=(0,255,0),flags=0)
第一阶段的典型结果如下所示:
然后在下一个循环中,对于每个真实输入图像,循环遍历所有训练图像以查看哪个匹配最佳:
ORBMatch=collections.namedtuple('ORBMatch',['dist','match','train'])
for img in inputImgs:
z2=preprocessNum(img)
orb=cv2.ORB_create(nfeatures=400,patchSize=30,edgeThreshold=0)
kp,des=orb.detectAndCompute(z2,None)
bf=cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
mm=[]
for train in orbTrained:
m=bf.match(des,train.des)
dist=sum([m_.distance for m_ in m])
mm.append(ORBMatch(dist=dist,match=m,train=train))
# sort matching images based on score
mm.sort(key=lambda m: m.dist)
print([m.dist for m in mm[:5]])
best=mm[0]
best.match.sort(key=lambda x:x.distance) # sort matches in the best match
z3=cv2.drawMatches(z2,kp,best.train.img,best.train.kp,best.match[:50],None,flags=2)
我得到的结果是荒谬的,并且始终如此(仅当我使用像素相同的输入运行时,结果才是正确的):
问题是什么?我完全误解了该怎么做,还是我只需要调整一些参数?
解决方案
推荐阅读
- c# - 组合框返回 System.Data.Entity.DynamicProxies.x
- c# - 特定于 WPF 信息亭应用程序 C# 的光标速度
- less - 更少的导入路径——它在哪里找到库?
- javascript - 同时循环遍历两个数组并在 Handlebars Ember 中打印
- google-apps-script - 如何在谷歌应用程序脚本中模拟搜索和替换范围
- mysql - 如何在序列中的最后一个 Gap 之后检索数据
- django - 为什么我在 django 中看不到图像文件?
- angular - angular/common/http 的 Nativescript 6.0 实现似乎破坏了 HttpHeaders。有解决办法吗?
- android - 在自定义视图 onDraw() 中绘制的项目不断消失
- javascript - 如何在Javascript中正确地将一列拆分为几列?