Opencv4.0 多目标模板匹配

opencv中关于模板匹配的算法:

matchTemplate( const CvArr* image, constCvArr* templ,CvArr* result,int method );

Image  待搜索图像

Templ  模板图像

Result  匹配结果  用来存放通过以下方法计算出滑动窗口与模板的相似值

Method  计算匹配程度的方法 (关于匹配方法,使用不同的方法产生的结果的意义可能不太一样,有些返回的值越大表示匹配程度越好,而有些方法返回的值越小表示匹配程度越好)

关于参数 method:
TM_SQDIFF平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。
TM_CCORR相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
TM_CCOEFF相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
TM_SQDIFF_NORMED归一化平方差匹配法
TM_CCORR_NORMED归一化相关匹配法
TM_CCOEFF_NORMED归一化相关系数匹配法
 

#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc.hpp>
#include <math.h>
#include <iostream>
#include <vector>

using namespace std;
using namespace cv;

//计算下一个最小值
Point getNextMinLoc(Mat result, Point minLoc, int maxVaule, int templatW, int templatH)
{
	// 先将第一个最小值点附近两倍模板宽度和高度的都设置为最大值防止产生干扰  
	int startX = minLoc.x - templatW;
	int startY = minLoc.y - templatH;
	int endX = minLoc.x + templatW;
	int endY = minLoc.y + templatH;
	if (startX < 0 || startY < 0)
	{
		startX = 0;
		startY = 0;
	}
	if (endX > result.cols - 1 || endY > result.rows - 1)
	{
		endX = result.cols - 1;
		endY = result.rows - 1;
	}
	for (int y = startY; y < endY; y++)
		for (int x = startX; x < endX; x++)
		{
			//cvsetReal2D(result, y, x, maxVaule);	
			result.at<float>(y, x) = maxVaule;
		}
		
			
	double new_minVaule, new_maxValue;
	Point new_minLoc, new_maxLoc;
	minMaxLoc(result, &new_minVaule, &new_maxValue, &new_minLoc, &new_maxLoc);
	return new_minLoc;
}

//模板匹配,多目标
int main()
{
	//加载(读取)图片
	Mat src = imread("src路径", 0);		//待匹配源图片 
	Mat templat = imread("template路径", 0); //模板图片
	Mat result;  // 模板匹配结果 

	//取得源图片和模板图片各自的宽和高
	int srcW, srcH, templatW, templatH;
	srcW = src.cols;
	srcH = src.rows;
	templatW = templat.cols;
	templatH = templat.rows;
	//模板图片不能比源图小,否则无法匹配
	if (srcW < templatW || srcH < templatH)
	{
		cout << "模板不能比原图小" << endl;
		return 0;
	}
	int resultW = srcW - templatW + 1;
	int resultH = srcH - templatH + 1;
	result.create(resultW, resultH, CV_32FC1);    //匹配方法计算的结果最小值为float 
	//开始模板匹配
	matchTemplate(src, templat, result, TM_SQDIFF); //方差最小,匹配最好
	normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

	double minValue, maxValue;
	Point minLoc, maxLoc;
	minMaxLoc(result, &minValue, &maxValue, &minLoc, &maxLoc, Mat());
	rectangle(src, minLoc, Point(minLoc.x + templatW, minLoc.y + templatH), Scalar(255, 0, 0), 2, 8, 0);

	//保存结果1
	Rect rect(minLoc.x, minLoc.y, templatW, templatH);//1 
	Mat image_roi = src(rect);

	//for (int i = 0; i < 5; i++)
	{
		//计算下一个最小值
		Point new_minLoc;
		new_minLoc = getNextMinLoc(result, minLoc, maxValue, templatW, templatH);
		rectangle(src, new_minLoc, Point(new_minLoc.x + templatW, new_minLoc.y + templatH), Scalar(255, 0, 0), 2, 8, 0);
		//保存结果2
		Rect rect2(new_minLoc.x, new_minLoc.y, templatW, templatH);//2
		image_roi = src(rect2);

		//再计算下一个最小值    
		new_minLoc = getNextMinLoc(result, new_minLoc, maxValue, templatW, templatH);
		rectangle(src, new_minLoc, Point(new_minLoc.x + templatW, new_minLoc.y + templatH), Scalar(255, 0, 0), 2, 8, 0);
		//保存结果3
		Rect rect3(new_minLoc.x, new_minLoc.y, templatW, templatH);//3
		image_roi = src(rect3);
	}

	imshow("匹配结果", src);//显示匹配结果(带匹配标识的源图)
	imshow("模板", templat);//显示模板
	
	waitKey(0);//鼠标按下,退出并释放资源
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值