为什么以及如何应用阈值来获得更好的匹配特征
Why and how apply thresholding to get better matched features
在下面的代码中,我正在使用 BRUTFORCE 算法进行描述符匹配。我阅读了一些教程,但它们是用 C++ 编写的,我发现,总是在匹配过程之后,来自
的结果 MatOfDMatch 对象
.match(query_desc, train_desc, MatOfDMatch objec)
应该如下转换为DMatch对象
List<DMatch> dMtchList = matDMatch.toList();
并且 dMtchList 应该按升序排序,然后应用阈值处理,然后将 dMtchList 对象转换为 MatOfDMatch。
我的问题是,为什么我们需要应用阈值,因为我可以对从 .match(..,..,..) 方法返回的原始匹配进行升序排序,以及阈值如何增强匹配。
**代码*:
private static void descriptorMatcher() {
// TODO Auto-generated method stub
MatOfDMatch matDMatch = new MatOfDMatch();//empty MatOfDmatch object
dm.match(matFactory.getComputedDescExtMatAt(0), matFactory.getComputedDescExtMatAt(1), matDMatch);//descriptor extractor of the query and the train image are used as parameters
matFactory.addRawMatchesMatDMatch(matDMatch);
/*writing the raw MatDMatches*/
Mat outImg = new Mat();
Features2d.drawMatches(matFactory.getMatAt(0), matFactory.getMatKeyPtsAt(0), matFactory.getMatAt(1), matFactory.getMatKeyPtsAt(1), MatFactory.lastAddedObj(matFactory.getRawMatchesMatDMatchList()),
outImg);
matFactory.addRawMatchedImage(outImg);
MatFactory.writeMat(FilePathUtils.newOutputPath(SystemConstants.RAW_MATCHED_IMAGE), MatFactory.lastAddedObj(matFactory.getRawMatchedImageList()));//this produce img_2 below posted
/*getting the top 10 shortest distance*/
List<DMatch> dMtchList = matDMatch.toList();
List<DMatch> goodDMatchList = MatFactory.getTopGoodMatches(dMtchList, 0, 10);//this method sort the dMatchList ascendingly and picks onlt the top 10 distances and assign these values to goodDMatchList
/*converting the goo DMatches to MatOfDMatches*/
MatOfDMatch goodMatDMatches = new MatOfDMatch();
goodMatDMatches.fromList(goodDMatchList);
matFactory.addGoodMatchMatDMatch(goodMatDMatches);
/*drawing the good matches and writing the good matches images*/
Features2d.drawMatches(matFactory.getMatAt(0), matFactory.getMatKeyPtsAt(0), matFactory.getMatAt(1), matFactory.getMatKeyPtsAt(1), MatFactory.lastAddedObj(matFactory.getGoodMatchMatDMatchList()),
outImg);
MatFactory.writeMat(FilePathUtils.newOutputPath(SystemConstants.GOOD_MATCHED_IMAGE), outImg);// this produce img_1 below posted
}
过滤可以让您精简匹配项,只保留最好的匹配项,并让您可以控制决定什么是好的匹配项,这也可以为您的结果赋予权重。
没有什么能阻止您选择前 10 个最接近的匹配项,但如果不将它们与某些标准或准则进行比较,它们就没有任何意义。
通过将自己限制在前 N 个匹配项中,您可能还会错过更多潜在的匹配项,尤其是当您从提取中返回了成百上千个匹配项时。
假设您正在比较两张图片 A 和 B。
如果您总共收到 1000 场比赛并且其中 900 场通过了您的一系列 threshold/filtering 检查,您可以说它们很可能相似。如果只有 50 个通过,则两张图片根本不相似。
但是,如果您只看前 10 名匹配项,您无法真正确定多少,如果图像或相似,它们可能是许多强匹配中最好的,或者如果图像非常不同,它们可能是许多弱匹配中最好的.
编辑 - 距离
距离是衡量两个关键点之间相似度的指标,距离越大相似度越低,距离越小相似度越高。
在您查看的示例中,最大和最小距离初始化如下:
[http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html]
double max_dist = 0; double min_dist = 100;
这只是为了用匹配列表中存在的实际 min/max 值更新它们。如果最小值从 0 开始,它可能永远不会被覆盖,对于最大距离,反之亦然。
for( int i = 0; i < descriptors_1.rows; i++ ){
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
在下面的代码中,我正在使用 BRUTFORCE 算法进行描述符匹配。我阅读了一些教程,但它们是用 C++ 编写的,我发现,总是在匹配过程之后,来自
的结果 MatOfDMatch 对象.match(query_desc, train_desc, MatOfDMatch objec)
应该如下转换为DMatch对象
List<DMatch> dMtchList = matDMatch.toList();
并且 dMtchList 应该按升序排序,然后应用阈值处理,然后将 dMtchList 对象转换为 MatOfDMatch。
我的问题是,为什么我们需要应用阈值,因为我可以对从 .match(..,..,..) 方法返回的原始匹配进行升序排序,以及阈值如何增强匹配。
**代码*:
private static void descriptorMatcher() {
// TODO Auto-generated method stub
MatOfDMatch matDMatch = new MatOfDMatch();//empty MatOfDmatch object
dm.match(matFactory.getComputedDescExtMatAt(0), matFactory.getComputedDescExtMatAt(1), matDMatch);//descriptor extractor of the query and the train image are used as parameters
matFactory.addRawMatchesMatDMatch(matDMatch);
/*writing the raw MatDMatches*/
Mat outImg = new Mat();
Features2d.drawMatches(matFactory.getMatAt(0), matFactory.getMatKeyPtsAt(0), matFactory.getMatAt(1), matFactory.getMatKeyPtsAt(1), MatFactory.lastAddedObj(matFactory.getRawMatchesMatDMatchList()),
outImg);
matFactory.addRawMatchedImage(outImg);
MatFactory.writeMat(FilePathUtils.newOutputPath(SystemConstants.RAW_MATCHED_IMAGE), MatFactory.lastAddedObj(matFactory.getRawMatchedImageList()));//this produce img_2 below posted
/*getting the top 10 shortest distance*/
List<DMatch> dMtchList = matDMatch.toList();
List<DMatch> goodDMatchList = MatFactory.getTopGoodMatches(dMtchList, 0, 10);//this method sort the dMatchList ascendingly and picks onlt the top 10 distances and assign these values to goodDMatchList
/*converting the goo DMatches to MatOfDMatches*/
MatOfDMatch goodMatDMatches = new MatOfDMatch();
goodMatDMatches.fromList(goodDMatchList);
matFactory.addGoodMatchMatDMatch(goodMatDMatches);
/*drawing the good matches and writing the good matches images*/
Features2d.drawMatches(matFactory.getMatAt(0), matFactory.getMatKeyPtsAt(0), matFactory.getMatAt(1), matFactory.getMatKeyPtsAt(1), MatFactory.lastAddedObj(matFactory.getGoodMatchMatDMatchList()),
outImg);
MatFactory.writeMat(FilePathUtils.newOutputPath(SystemConstants.GOOD_MATCHED_IMAGE), outImg);// this produce img_1 below posted
}
过滤可以让您精简匹配项,只保留最好的匹配项,并让您可以控制决定什么是好的匹配项,这也可以为您的结果赋予权重。
没有什么能阻止您选择前 10 个最接近的匹配项,但如果不将它们与某些标准或准则进行比较,它们就没有任何意义。
通过将自己限制在前 N 个匹配项中,您可能还会错过更多潜在的匹配项,尤其是当您从提取中返回了成百上千个匹配项时。
假设您正在比较两张图片 A 和 B。
如果您总共收到 1000 场比赛并且其中 900 场通过了您的一系列 threshold/filtering 检查,您可以说它们很可能相似。如果只有 50 个通过,则两张图片根本不相似。
但是,如果您只看前 10 名匹配项,您无法真正确定多少,如果图像或相似,它们可能是许多强匹配中最好的,或者如果图像非常不同,它们可能是许多弱匹配中最好的.
编辑 - 距离
距离是衡量两个关键点之间相似度的指标,距离越大相似度越低,距离越小相似度越高。
在您查看的示例中,最大和最小距离初始化如下:
[http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html]
double max_dist = 0; double min_dist = 100;
这只是为了用匹配列表中存在的实际 min/max 值更新它们。如果最小值从 0 开始,它可能永远不会被覆盖,对于最大距离,反之亦然。
for( int i = 0; i < descriptors_1.rows; i++ ){
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;