API

matchTemplate();//模式查找,API比较简单
minMaxLoc();//用于在模式查找的输出图像中找到极值点,也就是匹配点

笔记

  • 模板匹配(Templet Match)

    相当于上一节说的直方图匹配的实用化,通过现有图像在目标图像上滑行(原文Slide),也就是左到右上到下的以像素为单位进行匹配,找到匹配值最大的点.但也是因为这个原因,对模板图像和在目标图像里的目标的大小进行匹配就非常重要,如果大小差得远,效果就不好,所以使用条件相当苛刻.

  • 注意输出图像的大小

    在API中需要提供一个储存输出结果的Mat, 他的大小是

    Size(src.cols-templ.cols+1, src.rows-templ.rows+1)
    
  • OpenCV的查找模式

    OpenCV提供了很多种方法,在官网上都有介绍,大部分都是取用了最大值作为最匹配

    根据最小值匹配的只有 TM_SQDIFFMT_SQDIFF_NORMED

    For the first two methods ( TM_SQDIFF and MT_SQDIFF_NORMED ) the best match are the lowest values.

  • OpenCV中32位的图像

    每个数值是一个位于[0,1]间的小数,相当于8位的[0,255]


源//API实现模式查找

// OpenCV_Template.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<opencv2\opencv.hpp>

using namespace std;
using namespace cv;

Mat src, dst, temp;

int main(int, char**)
{
	temp = imread("D:/WorkSpace/Projects/OpenCV Learning/ImageHub/Lena.jpg");
	src = imread("D:/WorkSpace/Projects/OpenCV Learning/ImageHub/Day1.png");

	//测试尺度不变性
	//pyrDown(temp, temp, Size(temp.cols / 2, temp.rows / 2));
	pyrUp(temp, temp, Size(temp.cols * 2, temp.rows * 2));
	//pyrUp(temp, temp, Size(temp.cols * 2, temp.rows * 2));

	if (temp.empty() || src.empty()) {
		cout << "Can not open this IMG... Check again!";
		return -1;
	}

	Mat result = Mat_<float>::zeros(src.cols - temp.cols + 1, src.rows - temp.rows + 1 );

	matchTemplate(src, temp, result, TM_CCOEFF_NORMED);

	//cout << result;

	double minVal; double maxVal; Point minLoc; Point maxLoc;
	Point matchLoc;
	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
	cout << minVal << endl << maxVal << endl << minLoc << endl << maxLoc << endl;
	rectangle(src, maxLoc, Point(maxLoc.x + temp.cols, maxLoc.y + temp.rows), Scalar(0,0,255), 2, 8);
	rectangle(result, Point(maxLoc.x - temp.cols/2, maxLoc.y - temp.rows/2), Point(maxLoc.x + temp.cols/2, maxLoc.y + temp.rows/2), Scalar::all(1), 2, 8, 0);

	namedWindow("src", WINDOW_AUTOSIZE);
	pyrDown(src, src, Size(src.cols / 2, src.rows / 2));
	pyrDown(src, src, Size(src.cols / 2, src.rows / 2));
	imshow("src", src);
	namedWindow("result", WINDOW_AUTOSIZE);
	pyrDown(result, result, Size(result.cols / 2, result.rows / 2));
	pyrDown(result, result, Size(result.cols / 2, result.rows / 2));
	imshow("result", result);

	waitKey(0);
	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件