Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有阈值/相似性分数的OpenCV特征匹配的对象检测-Java/C++;_Opencv_Image Processing_Feature Detection_Object Detection_Feature Extraction - Fatal编程技术网

具有阈值/相似性分数的OpenCV特征匹配的对象检测-Java/C++;

具有阈值/相似性分数的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

我正在创建一个小程序来检测大图像中的对象(小图像),我正在使用OpenCV java。 当我必须考虑旋转和缩放时,我使用了TraveDebug。p> 以下方法用于过滤匹配结果,以仅获得最佳匹配

我有两个问题

  • 有没有办法通过我使用的循环找到下面的最小距离和最大距离
  • 最重要的问题-现在的问题是我需要使用这些匹配来确定是否找到了对象(模板)。如果有人能在这里帮我就好了
  • 提前谢谢

        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章
    最后一个链接显示了计算最小值和最大值的方法,在Java中应该几乎相同。希望所有链接都能展示一些如何匹配对象的想法


    我还认识到在你的代码中有很多神奇的数字。也许您可以将它们放在变量中,以减少出错的可能性,并有更好的概述。

    您编辑的代码对我来说运行良好,工作完美

    以下是我在您的代码中为在大图像中检测对象(小图像)所做的更改:

  • 使用SURF方法进行特征检测和特征提取。(适用于Android和更早版本的opencv 4.1.1中提供了SURF,之后它已从中删除,因此我在这里使用了opencv 4.1.1)

  • 将匹配或不匹配图像的阈值从1更改为4,如下所示

    if(matchesFiltered.rows()>=1)


  • 只有这些更改对我来说才是完美的,请确保对象/小图像具有丰富的纹理(至少应该有可以匹配的关键点)

    感谢您的参考,实际上我已经开始在第二个链接:-)中使用教程编写此代码。
    if(matchesFiltered.rows() >= 4)