我正在使用openCV识别来自不同密度设备的图标,图标以不同的尺寸显示不同密度的设备。 如果模板大小与screencapture中显示的图标相同,则可以找到正确的位置,但如果没有,则无法找到正确的位置,甚至完全错误。 那么,我想知道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,但看结果,match.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)
模板匹配就是这样,它寻找“像素像素”相关性。它无法处理规模变化。
如果您有不同尺寸的图像,则应重新缩放图像或模板。
如果只有几个可能的比例,你可以保留多个预先缩放的模板,并为每个案例使用正确的模板,或者只是尝试所有模板并且只是最佳匹配。
答案 1 :(得分:0)
如果模板的比例或方向可能不同,则matchTemplate
将失败。 matchTemplate
是opencv中用于检测场景中对象的最简单,最弱的方法
我想你看到了特征检测,描述和匹配的主题。它认为以下将是一个很好的起点: