当前位置: 代码迷 >> 综合 >> Opencv4.0 多目标模板匹配
  详细解决方案

Opencv4.0 多目标模板匹配

热度:50   发布时间:2023-12-16 07:58:56.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);//保存结果1Rect 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);//保存结果2Rect rect2(new_minLoc.x, new_minLoc.y, templatW, templatH);//2image_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);//保存结果3Rect rect3(new_minLoc.x, new_minLoc.y, templatW, templatH);//3image_roi = src(rect3);}imshow("匹配结果", src);//显示匹配结果(带匹配标识的源图)imshow("模板", templat);//显示模板waitKey(0);//鼠标按下,退出并释放资源return 0;
}

  相关解决方案