Bhu*_*han 0 java opencv image-processing
我正在使用OpenCV(opencv_java248)。我有一张模板图片。这个模板图像有一些公司的标志。我想知道这个标志是否包含在其他图像中。我在某处得到了以下代码。
public void run(String inFile, String templateFile, String outFile,
int match_method) {
System.out.println("Running Template Matching");
Mat img = Highgui.imread(inFile);
Mat templ = Highgui.imread(templateFile);
// / Create the result matrix
int result_cols = img.cols() - templ.cols() + 1;
int result_rows = img.rows() - templ.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
// / Do the Matching and Normalize
Imgproc.matchTemplate(img, templ, result, match_method);
// Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new
// Mat());
Imgproc.threshold(result, result, 0.5, 1.0, Imgproc.THRESH_TOZERO);
// / Localizing the best match with minMaxLoc
MinMaxLocResult mmr = Core.minMaxLoc(result);
Point matchLoc;
if (match_method == Imgproc.TM_SQDIFF
|| match_method == Imgproc.TM_SQDIFF_NORMED) {
matchLoc = mmr.minLoc;
} else {
matchLoc = mmr.maxLoc;
}
double threashhold = 0.40;
if (mmr.maxVal > threashhold) {
Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),
matchLoc.y + templ.rows()), new Scalar(0, 255, 0));
}
// Save the visualized detection.
Highgui.imwrite(outFile, img);
}
Run Code Online (Sandbox Code Playgroud)
您想要匹配的某些图像或某些代码将非常有用。
我不知道 Java API,但最近确实研究了用 C++ 编写的类似内容。转换应该相当简单,因为任何一种语言的过程都是相同的。
首先像往常一样执行模板匹配,读入你的图像并创建一个垫子来保存结果。
cv::Mat drawing = cv::imread(_drawing); //Read drawing
cv::Mat tmp = cv::imread(_tmp); //Read template
cv::Mat res(drawing.rows - tmp.rows + 1, drawing.cols - tmp.cols + 1, CV_32FC1); //Create result matrix
//Perform template matching, normalise results 0 -> 1
cv::matchTemplate(tmp, drawing, res, CV_TM_CCOEFF_NORMED);
cv::threshold(res, res, 0.8, 1.0, CV_THRESH_TOZERO); //Can thresh to filter results if needed
Run Code Online (Sandbox Code Playgroud)
现在结果已填充,创建变量以保存最小/最大分数及其在结果矩阵中的位置。
容差值用于过滤可接受的结果,其中 1.0 可被视为 100% 匹配,0.25 可被视为 25%。
//min/max values and acceptable tolerance
double min, max, tolerance = 0.90;
cv::Point minloc, maxloc; //min/max value locations
Run Code Online (Sandbox Code Playgroud)
现在从结果中提取值并根据您的容差检查最大值,如果它在容差范围内,则表示匹配。
您还可以循环此过程并检查所有结果,以查看您的图像是否包含多次出现的模板。
//Loop through all results
while (true){
//Pull out min/max values from results matrix
cv::minMaxLoc(res, &min, &max, &minloc, &maxloc);
//Is max within tolerance
if (max >= tolerance){
//Yes - Match found, do stuff //
//Blank out that result in matrix so next highest can be extracted
cv::floodFill(res, maxloc, cv::Scalar(0), 0, cv::Scalar(0.1), cv::Scalar(1.0));
}
else
break; //No more results within tolerance, break search
}
Run Code Online (Sandbox Code Playgroud)
您可能需要试验容差/图像质量以及什么才算合格。但是对于简单的匹配,这很有效。
编辑 - 模板匹配和缩放
标准模板匹配在缩放方面的表现非常差,仅仅是因为它的工作方式 - 搜索窗口只能与提供的模板一样小,因此找到任何更小(或更大)的东西将是困难的。
为比例不变性优化模板匹配并不是最简单的事情,您可以尝试的一种简单方法是创建模板的缩放变体(查看 OpenCVs Image Pyramids)。
如果有兴趣,还有很多论文涵盖了模板匹配的更高级变体(谷歌搜索会带来最多)。
您可能想要研究对缩放和旋转不变的特征检测。
同样,如果您可以发布有助于帮助您的徽标图片和搜索图片,那么可能有一个简单的替代方法。