我目前正在使用各种特征提取器和各种匹配器制作识别程序。使用匹配器的分数,我想创建一个分数阈值,它可以进一步确定它是正确匹配还是错误匹配。
我正在尝试了解各种匹配器的 DMatch 距离含义,距离值越小匹配越好吗?如果是,我很困惑,因为具有不同位置的相同图像返回的值比两个不同的图像更大。
我运行了两个测试用例:
-----------------------------------------------
Positive image average distance
Total test number: 70
Comparing with SIFT
Use BF with Ratio Test: 874.071456255
Use FLANN : 516.737270464
Comparing with SURF
Use BF with Ratio Test: 2.92960552163
Use FLANN : 1.47225751158
Comparing with ORB
Use BF : 12222.1428571
Use BF with Ratio Test: 271.638643755
Comparing with BRISK
Use BF : 31928.4285714
Use BF with Ratio Test: 1537.63658578
Maximum positive image distance
Comparing with SIFT
Use BF with Ratio Test: 2717.88008881
Use FLANN : 1775.63563538
Comparing with SURF
Use BF with Ratio Test: 4.88817568123
Use FLANN : 2.81848525628
Comparing with ORB
Use BF : 14451.0
Use BF with Ratio Test: 1174.47851562
Comparing with BRISK
Use BF : 41839.0
Use BF with Ratio Test: 3846.39746094
-----------------------------------------
Negative image average distance
Total test number: 72
Comparing with SIFT
Use BF with Ratio Test: 750.028228866
Use FLANN : 394.982576052
Comparing with SURF
Use BF with Ratio Test: 2.89866939275
Use FLANN : 1.59815886725
Comparing with ORB
Use BF : 12098.9444444
Use BF with Ratio Test: 261.874231339
Comparing with BRISK
Use BF : 31165.8472222
Use BF with Ratio Test: 1140.46670034
Minimum negative image distance
Comparing with SIFT
Use BF with Ratio Test: 0
Use FLANN : 0
Comparing with SURF
Use BF with Ratio Test: 1.25826786458
Use FLANN : 0.316588282585
Comparing with ORB
Use BF : 10170.0
Use BF with Ratio Test: 0
Comparing with BRISK
Use BF : 24774.0
Use BF with Ratio Test: 0
同样在某些情况下,当两个不同的图像相互测试并且没有匹配时,匹配器也会返回 0 个分数,这与两个相同的图像一起比较时的分数完全相同。
进一步考察,主要有四种情况:
根据这些案例找到正确的阈值似乎是个问题,因为有些案例相互矛盾。 通常图像越相似,距离值越小。
def useBruteForce(img1, img2, kp1, kp2, des1, des2, setDraw):
# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Match descriptors.
matches = bf.match(des1,des2)
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
totalDistance = 0
for g in matches:
totalDistance += g.distance
if setDraw == True:
# Draw matches.
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches, None, flags=2)
plt.imshow(img3),plt.show()
return totalDistance
def useBruteForceWithRatioTest(img1, img2, kp1, kp2, des1, des2, setDraw):
# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)
# Apply ratio test
good = []
for m,n in matches:
if m.distance < 0.75*n.distance:
good.append(m)
totalDistance = 0
for g in good:
totalDistance += g.distance
if setDraw == True:
# cv2.drawMatchesKnn expects list of lists as matches.
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None,flags=2)
plt.imshow(img3),plt.show()
return totalDistance
def useFLANN(img1, img2, kp1, kp2, des1, des2, setDraw, type):
# Fast Library for Approximate Nearest Neighbors
MIN_MATCH_COUNT = 1
FLANN_INDEX_KDTREE = 0
FLANN_INDEX_LSH = 6
if type == True:
# Detect with ORB
index_params= dict(algorithm = FLANN_INDEX_LSH,
table_number = 6, # 12
key_size = 12, # 20
multi_probe_level = 1) #2
else:
# Detect with Others such as SURF, SIFT
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
# It specifies the number of times the trees in the index should be recursively traversed. Higher values gives better precision, but also takes more time
search_params = dict(checks = 90)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)
# store all the good matches as per Lowe's ratio test.
good = []
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append(m)
totalDistance = 0
for g in good:
totalDistance += g.distance
if setDraw == True:
if len(good)>MIN_MATCH_COUNT:
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
matchesMask = mask.ravel().tolist()
h,w = img1.shape
pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
dst = cv2.perspectiveTransform(pts,M)
img2 = cv2.polylines(img2,[np.int32(dst)],True,255,3, cv2.LINE_AA)
else:
print "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT)
matchesMask = None
draw_params = dict(matchColor = (0,255,0), # draw matches in green color
singlePointColor = None,
matchesMask = matchesMask, # draw only inliers
flags = 2)
img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)
plt.imshow(img3, 'gray'),plt.show()
return totalDistance
import matcher
def check(img1, img2, kp1, kp2, des1, des2, matcherType, setDraw, ORB):
if matcherType == 1:
return matcher.useBruteForce(img1, img2, kp1, kp2, des1, des2, setDraw)
elif matcherType == 2:
return matcher.useBruteForceWithRatioTest(img1, img2, kp1, kp2, des1, des2, setDraw)
elif matcherType == 3:
return matcher.useFLANN(img1, img2, kp1, kp2, des1, des2, setDraw, ORB)
else:
print "Matcher not chosen correctly, use Brute Force matcher as default"
return matcher.useBruteForce(img1, img2, kp1, kp2, des1, des2, matcherType, setDraw)
def useORB(filename1, filename2, matcherType, setDraw):
img1 = cv2.imread(filename1,0) # queryImage
img2 = cv2.imread(filename2,0) # trainImage
# Initiate ORB detector
orb = cv2.ORB_create()
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)
ORB = True
return check(img1, img2, kp1, kp2, des1, des2, matcherType, setDraw, ORB)
def useSIFT(filename1, filename2, matcherType, setDraw):
img1 = cv2.imread(filename1,0) # queryImage
img2 = cv2.imread(filename2,0) # trainImage
# Initiate SIFT detector
sift = cv2.xfeatures2d.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
ORB = False
return check(img1, img2, kp1, kp2, des1, des2, matcherType, setDraw, ORB)
def useSURF(filename1, filename2, matcherType, setDraw):
img1 = cv2.imread(filename1, 0)
img2 = cv2.imread(filename2, 0)
# Here I set Hessian Threshold to 400
surf = cv2.xfeatures2d.SURF_create(400)
# Find keypoints and descriptors directly
kp1, des1 = surf.detectAndCompute(img1, None)
kp2, des2 = surf.detectAndCompute(img2, None)
ORB = False
return check(img1, img2, kp1, kp2, des1, des2, matcherType, setDraw, ORB)
def useBRISK(filename1, filename2, matcherType, setDraw):
img1 = cv2.imread(filename1,0) # queryImage
img2 = cv2.imread(filename2,0) # trainImage
# Initiate BRISK detector
brisk = cv2.BRISK_create()
# find the keypoints and descriptors with BRISK
kp1, des1 = brisk.detectAndCompute(img1,None)
kp2, des2 = brisk.detectAndCompute(img2,None)
ORB = True
return check(img1, img2, kp1, kp2, des1, des2, matcherType, setDraw, ORB)
最佳答案
在OpenCV的教程中,是这样说的
For BF matcher, first we have to create the BFMatcher object using cv.BFMatcher(). It takes two optional params. First one is normType. It specifies the distance measurement to be used. By default, it is cv.NORM_L2. It is good for SIFT, SURF etc (cv.NORM_L1 is also there). For binary string based descriptors like ORB, BRIEF, BRISK etc, cv.NORM_HAMMING should be used, which used Hamming distance as measurement. If ORB is using WTA_K == 3 or 4, cv.NORM_HAMMING2 should be used.
https://docs.opencv.org/3.4/dc/dc3/tutorial_py_matcher.html
所以您应该为 SIFT 和 ORB 创建不同的匹配器对象(您明白了)。这可能就是您计算的距离差异如此之大的原因。
关于python - OpenCV 找到正确的阈值来确定图像匹配与否与匹配分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43423411/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。
我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
我正在学习http://ruby.railstutorial.org/chapters/static-pages上的RubyonRails教程并遇到以下错误StaticPagesHomepageshouldhavethecontent'SampleApp'Failure/Error:page.shouldhave_content('SampleApp')Capybara::ElementNotFound:Unabletofindxpath"/html"#(eval):2:in`text'#./spec/requests/static_pages_spec.rb:7:in`(root)'
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o