具有阈值/相似性分数的OpenCV特征匹配的对象检测-Java/C++;
我正在创建一个小程序来检测大图像中的对象(小图像),我正在使用OpenCV java。 当我必须考虑旋转和缩放时,我使用了TraveDebug。p> 以下方法用于过滤匹配结果,以仅获得最佳匹配 我有两个问题具有阈值/相似性分数的OpenCV特征匹配的对象检测-Java/C++;,opencv,image-processing,feature-detection,object-detection,feature-extraction,Opencv,Image Processing,Feature Detection,Object Detection,Feature Extraction,我正在创建一个小程序来检测大图像中的对象(小图像),我正在使用OpenCV java。 当我必须考虑旋转和缩放时,我使用了TraveDebug。p> 以下方法用于过滤匹配结果,以仅获得最佳匹配 我有两个问题 有没有办法通过我使用的循环找到下面的最小距离和最大距离 最重要的问题-现在的问题是我需要使用这些匹配来确定是否找到了对象(模板)。如果有人能在这里帮我就好了 提前谢谢 FeatureDetector fd = FeatureDetector.create(FeatureDetect
FeatureDetector fd = FeatureDetector.create(FeatureDetector.BRISK);
final MatOfKeyPoint keyPointsLarge = new MatOfKeyPoint();
final MatOfKeyPoint keyPointsSmall = new MatOfKeyPoint();
fd.detect(largeImage, keyPointsLarge);
fd.detect(smallImage, keyPointsSmall);
System.out.println("keyPoints.size() : "+keyPointsLarge.size());
System.out.println("keyPoints2.size() : "+keyPointsSmall.size());
Mat descriptorsLarge = new Mat();
Mat descriptorsSmall = new Mat();
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.BRISK);
extractor.compute(largeImage, keyPointsLarge, descriptorsLarge);
extractor.compute(smallImage, keyPointsSmall, descriptorsSmall);
System.out.println("descriptorsA.size() : "+descriptorsLarge.size());
System.out.println("descriptorsB.size() : "+descriptorsSmall.size());
MatOfDMatch matches = new MatOfDMatch();
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);
matcher.match(descriptorsLarge, descriptorsSmall, matches);
System.out.println("matches.size() : "+matches.size());
MatOfDMatch matchesFiltered = new MatOfDMatch();
List<DMatch> matchesList = matches.toList();
List<DMatch> bestMatches= new ArrayList<DMatch>();
Double max_dist = 0.0;
Double min_dist = 100.0;
for (int i = 0; i < matchesList.size(); i++)
{
Double dist = (double) matchesList.get(i).distance;
if (dist < min_dist && dist != 0)
{
min_dist = dist;
}
if (dist > max_dist)
{
max_dist = dist;
}
}
System.out.println("max_dist : "+max_dist);
System.out.println("min_dist : "+min_dist);
double threshold = 3 * min_dist;
double threshold2 = 2 * min_dist;
if (threshold2 >= max_dist)
{
threshold = min_dist * 1.1;
}
else if (threshold >= max_dist)
{
threshold = threshold2 * 1.4;
}
System.out.println("Threshold : "+threshold);
for (int i = 0; i < matchesList.size(); i++)
{
Double dist = (double) matchesList.get(i).distance;
System.out.println(String.format(i + " match distance best : %s", dist));
if (dist < threshold)
{
bestMatches.add(matches.toList().get(i));
System.out.println(String.format(i + " best match added : %s", dist));
}
}
matchesFiltered.fromList(bestMatches);
System.out.println("matchesFiltered.size() : " + matchesFiltered.size());
FeatureDetector fd=FeatureDetector.create(FeatureDetector.BRISK);
最终MatOfKeyPoint关键点RGE=新MatOfKeyPoint();
最终MatOfKeyPoint keyPointsSmall=新MatOfKeyPoint();
fd.检测(大图像、关键点变大);
fd.检测(小图像,关键点小);
System.out.println(“keyPoints.size():”+keyPointsLarge.size());
System.out.println(“keyPoints2.size():”+keyPointsSmall.size());
Mat描述符大=新Mat();
材料描述符小=新材料();
DescriptorExtractor提取器=DescriptorExtractor.create(DescriptorExtractor.BRISK);
compute(大图像,关键点大,描述符大);
compute(smallImage,keyPointsSmall,descriptorsmall);
System.out.println(“descriptorrsa.size():”+descriptorsragle.size());
System.out.println(“descriptorsB.size():”+descriptorsmall.size());
MatOfDMatch matches=新的MatOfDMatch();
DescriptorMatcher matcher=DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);
matcher.match(描述符大,描述符小,匹配);
System.out.println(“matches.size():”+matches.size());
MatOfDMatch matchesFiltered=新的MatOfDMatch();
List matchesList=matches.toList();
List bestMatches=new ArrayList();
双最大距离=0.0;
双最小距离=100.0;
对于(int i=0;i最大距离)
{
最大距离=距离;
}
}
系统输出打印项次(“最大距离:+最大距离”);
系统输出打印项次(“最小距离:+最小距离”);
双阈值=3*最小距离;
双阈值2=2*最小距离;
如果(阈值2>=最大距离)
{
阈值=最小距离*1.1;
}
否则如果(阈值>=最大距离)
{
阈值=阈值2*1.4;
}
System.out.println(“阈值:+阈值”);
对于(int i=0;i
编辑 按如下方式编辑了我的代码。我知道这仍然不是得出结论的最佳方法,不管对象是否找到,都是基于没有最佳匹配。 所以请分享你的观点
System.out.println("max_dist : "+max_dist);
System.out.println("min_dist : "+min_dist);
if(min_dist > 50 )
{
System.out.println("No match found");
System.out.println("Just return ");
return false;
}
double threshold = 3 * min_dist;
double threshold2 = 2 * min_dist;
if (threshold > 75)
{
threshold = 75;
}
else if (threshold2 >= max_dist)
{
threshold = min_dist * 1.1;
}
else if (threshold >= max_dist)
{
threshold = threshold2 * 1.4;
}
System.out.println("Threshold : "+threshold);
for (int i = 0; i < matchesList.size(); i++)
{
Double dist = (double) matchesList.get(i).distance;
if (dist < threshold)
{
bestMatches.add(matches.toList().get(i));
//System.out.println(String.format(i + " best match added : %s", dist));
}
}
matchesFiltered.fromList(bestMatches);
System.out.println("matchesFiltered.size() : " + matchesFiltered.size());
if(matchesFiltered.rows() >= 1)
{
System.out.println("match found");
return true;
}
else
{
return false;
}
System.out.println(“最大距离:+最大距离”);
系统输出打印项次(“最小距离:+最小距离”);
如果(最小距离>50)
{
System.out.println(“未找到匹配项”);
System.out.println(“刚刚返回”);
返回false;
}
双阈值=3*最小距离;
双阈值2=2*最小距离;
如果(阈值>75)
{
阈值=75;
}
否则如果(阈值2>=最大距离)
{
阈值=最小距离*1.1;
}
否则如果(阈值>=最大距离)
{
阈值=阈值2*1.4;
}
System.out.println(“阈值:+阈值”);
对于(int i=0;i=1)
{
System.out.println(“找到匹配项”);
返回true;
}
其他的
{
返回false;
}
有几种方法可以检测图像中的物体。只需在此处放置一些链接:
- ,第8/9章
我还认识到在你的代码中有很多神奇的数字。也许您可以将它们放在变量中,以减少出错的可能性,并有更好的概述。您编辑的代码对我来说运行良好,工作完美 以下是我在您的代码中为在大图像中检测对象(小图像)所做的更改:
只有这些更改对我来说才是完美的,请确保对象/小图像具有丰富的纹理(至少应该有可以匹配的关键点)感谢您的参考,实际上我已经开始在第二个链接:-)中使用教程编写此代码。
if(matchesFiltered.rows() >= 4)