2015-02-11 254 views
-1

我使用openCV识别来自不同密度设备的图标,该图标以不同大小显示不同密度的设备。 如果模板大小与screencapture中显示的图标相同,则可以找到正确的位置,但如果不是,则无法找到正确的位置,甚至完全错误。 那么,我想知道可以opencv templateMatch支持大小不匹配模板吗?可以opencv templateMatch支持大小不匹配模板?

这里是我的代码:

imgPath = "/sdcard/screencapture.png"; 
    Mat img = getMatFromFile(imgPath); 
    Mat templ = null; 
    try { 
     templ = getMatFromInputStream(getAssets().open("home_big.png")); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    Log.i(TAG, "templ.type()="+templ.type()); 
    Log.i(TAG, "img.type()="+img.type()); 
    Log.i(TAG, "templ.depth()="+templ.depth()); 
    Log.i(TAG, "img.depth()="+img.depth()); 

    Mat result = new Mat(); 
    Imgproc.matchTemplate(img, templ, result, Imgproc.TM_CCORR_NORMED); 

    MinMaxLocResult minMaxLocResult = Core.minMaxLoc(result, new Mat()); 
    Point matchLoc = minMaxLocResult.maxLoc; 
    Log.i(TAG, "match result="+matchLoc); 
    Log.i(TAG, "maxVal ="+minMaxLocResult.maxVal); 

我也试过功能检测,我打印匹配点,并参考了x时,图像和模板两者的Y,但是看看结果,本场比赛.distance = 0匹配点,意思是特征相等,x,y不在匹配区域,我不能依靠这个来找出图像中模板的正确位置。任何身体可以帮助吗? 这里是我的代码: 其实我尝试使用功能检测,但结果让我迷惑,这里是我的代码:

imgPath = "/sdcard/screencapture_htc.png"; 
    Mat img = getMatFromFile(imgPath, Highgui.CV_LOAD_IMAGE_GRAYSCALE); 
    Mat templ = null; 
    try { 
     templ = getMatFromInputStream(getAssets().open("icon.png"), Highgui.CV_LOAD_IMAGE_GRAYSCALE); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    FeatureDetector detector = FeatureDetector.create(FeatureDetector.FAST); 
    DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.BRIEF); 
    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_L1); 


    Mat descriptors1 = new Mat(); 
    Mat descriptors2 = new Mat(); 
    MatOfKeyPoint keypoints1 = new MatOfKeyPoint(); 
    MatOfKeyPoint keypoints2 = new MatOfKeyPoint(); 
    detector.detect(img, keypoints1); 
    detector.detect(templ, keypoints2); 

    List<KeyPoint> keypoints1List = keypoints1.toList(); 
    List<KeyPoint> keypoints2List = keypoints2.toList(); 

    extractor.compute(img, keypoints1, descriptors1); 
    extractor.compute(templ, keypoints2, descriptors2); 

    MatOfDMatch matches= new MatOfDMatch(); 
    matcher.match(descriptors1, descriptors2, matches); 

    Log.i(TAG, "matches.size() = "+matches.size()); 
    Log.i(TAG, "matches.toArray() = "+matches.toArray()); 

    List<DMatch> matchList = matches.toList(); 

    if(matchList != null){ 
     matchList = filterGoodMatch(matchList); 

     MatchComparator matchComparator = new MatchComparator(); 
     Collections.sort(matchList, matchComparator); 

     int goodMatchCount = matchList.size(); 
     List<DMatch> goodMatchList = matchList.subList(0, goodMatchCount > MAX ? MAX - 1 : goodMatchCount - 1); 

     Log.i(TAG, "match result:"); 
     Log.i(TAG, "**************************"); 
     for(DMatch match:goodMatchList){ 
      Log.i(TAG, "match.distance = "+match.distance); 
      Log.i(TAG, "img point = "+keypoints1List.get(match.queryIdx)); 
      Log.i(TAG, "train point = "+keypoints2List.get(match.trainIdx)); 
      Log.i(TAG, "**************************"); 
     } 
    }else{ 
     Log.i(TAG, "no match"); 
    } 

回答

0

模板匹配了这一点,它会寻找“像素超像素“相关性。它无法处理比例​​变化。

如果您有不同比例的图像,您应该重新缩放图像或模板。

如果只有几个可能的比例尺,您可以保留多个预先缩放的模板,并针对每个案例使用正确的模板,或者只是尝试所有的比例和最佳匹配。

+0

感谢您的快速回复,任何好主意,实现这一目标?我也试过FeatureDetector,但仍然无法获得好的结果。我需要找出目标图像上的正确位置。 – 2015-02-11 08:41:41

+0

正如我所说,*“如果只有几个可能的比例尺,您可以保留多个预缩放模板,并针对每个案例使用正确的模板,或者只是尝试所有模板,并且只匹配最佳匹配。”* – 2015-02-11 08:42:48

0

如果您的模板的比例或方向可能会有所不同,那么matchTemplate将会失败。 matchTemplate是opencv中用于检测场景中对象的最简单和最弱的方法。
我想你会看到关于特征检测,描述和匹配的主题。它认为,以下将是一个很好的出发点,为您提供:

+0

感谢回复,我尝试了功能检测,但感到困惑,你能看到我的更新吗? – 2015-02-11 09:31:56