您好我在Emgu中编写模板匹配函数(C#的OpenCV包装器)。 一般而言,我正在尝试为100个最佳匹配编写匹配模板功能。 我已经为CPU和GPU做了matchtemplate,但是我只能获得1个maxLocation(只有1个搜索模板,在源img中大约有10个)。我已经阅读了有关FloodFill的内容,可以删除最大的内容并再次调用MinMax将获得第二个最大值。但是我无法写出来(我花了大约2天的时间,所以我无望)
string path = @"C:\Users\Samuel\Desktop";
string imgtemplate = path+@"\TV.bmp";//smallImg
string imgsource = path+ @"\desktop.bmp";//bigImg
Image<Bgr, byte> source = new Image<Bgr, byte>(Imgsource);
Image<Bgr, byte> template = new Image<Bgr, byte>(Imgtemplate);
using (Image<Gray, float> result = source.MatchTemplate(template, TemplateMatchingType.SqdiffNormed))
{
double[] minValues, maxValues;
Point[] minLocations, maxLocations;
result.MinMax(out minValues, out maxValues, out minLocations, out maxLocations);
Console.WriteLine("minVal: " + minValues[0] + " maxVal: " + maxValues[0] + " minLoc: " + minLocations[0] + " maxLoc: " + maxLocations[0]);
}
我非常感谢你的帮助。 谢谢!
答案 0 :(得分:1)
我不熟悉C#,但这是一个用C ++编写的代码,可以完成你想要做的事情:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/videoio/videoio.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat imgSrc, mask;
Mat templatePatch, match;
imgSrc = imread("C:/Users/be92136/Documents/Qt_Projects/Videos/grimpe1.png", IMREAD_GRAYSCALE);
templatePatch = imgSrc(Rect(50, 50, 50, 50));
Point maxLoc;
Size patchSize = Size(50, 50);
matchTemplate(imgSrc, templatePatch, match, CV_TM_CCOEFF_NORMED);
mask = Mat::ones(match.size(), CV_8UC1);
for(int i=0; i<100; i++)
{
minMaxLoc(match, NULL, NULL, NULL, &maxLoc, mask);
Rect bestMatch = Rect(maxLoc, patchSize);
Mat roi = mask(bestMatch);
roi.setTo(0);
}
return 0;
}
它使用一个在开头填充了一个的掩码(这意味着minMaxLoc函数将整个匹配图像考虑在内)。每次找到新的最大值时,都会从掩码中删除给定区域,下次调用minMaxLoc时不会考虑该区域。