opencv模板匹配

模板匹配:
模板匹配实际上就是模板图在源图中的平移,所以只能匹配到一模一样(形态和方向都一致)的局部图像

demo1:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
int main()
{
    //加载源图像和模板图像
    cv::Mat image_source = cv::imread("1.bmp", cv::IMREAD_GRAYSCALE);
    cv::Mat image_template = cv::imread("7.png", cv::IMREAD_GRAYSCALE);
    //cv::Mat image_source = cv::imread("lena.jpg", cv::IMREAD_GRAYSCALE);
    //cv::Mat image_template = cv::imread("template.jpg", cv::IMREAD_GRAYSCALE);

    cv::Mat image_matched;

    //模板匹配方法
    cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCOEFF_NORMED);//归一化的平方差
    //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_SQDIFF);//平方差
    //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCORR);  //相关性匹配
    //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCORR_NORMED);//归一化的相关性匹配
    //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCOEFF);//相关性系数匹配
    //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCOEFF_NORMED);//归一化的相关性系数匹配

    double minVal, maxVal;
    cv::Point minLoc, maxLoc;
    //寻找最佳匹配位置 //参数:单通道阵列、最小值的指针、最大值的指针、最小位置的指针、最大位置的指针
    cv::minMaxLoc(image_matched, &minVal, &maxVal, &minLoc, &maxLoc);

    cv::Mat image_color;
    cv::cvtColor(image_source, image_color, CV_GRAY2BGR);
    //circle()参数:图像(单通道或多通道)
    cv::circle(image_color,  //将匹配到的用圆圈绘制出
               cv::Point(maxLoc.x + image_template.cols/2, maxLoc.y + image_template.rows/2),  //圆心坐标
               100,  //圆半径
               cv::Scalar(0, 0, 255), //圆的颜色
               2,  //线条粗细
               8,
               0);
    namedWindow("source image",CV_WINDOW_NORMAL);   //可调节窗口大小
    namedWindow("match result",CV_WINDOW_NORMAL);   //可调节窗口大小
    namedWindow("target",CV_WINDOW_NORMAL);   //可调节窗口大小
    cv::imshow("source image", image_source);
    cv::imshow("match result", image_matched);
    cv::imshow("target", image_color);
    cv::waitKey(0);

    return 0;
}

demo2:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<string>


using namespace cv;
using namespace std;

int max_track = 5;
int match_method = CV_TM_SQDIFF;
String Source_path = "1.bmp";
String Temp_path = "3.png";
String src_window = "Source Window";
String temp_window = "Temp Window";
String Output_window = "Output Window";

Mat src, temp;
void Match_Demo(int, void*);

int main()
{
    src = imread(Source_path, IMREAD_COLOR);
    temp = imread(Temp_path, IMREAD_COLOR);
    if (!src.data || !temp.data)
    {
        printf("Could not load the src image or temp image...");
        return false;
    }
    //namedWindow(src_window, CV_WINDOW_AUTOSIZE);
    //imshow(src_window, src);
    namedWindow(temp_window, CV_WINDOW_NORMAL);
    imshow(temp_window, temp);

    const char* trackbar_title = "Match Algo Type";
    namedWindow(Output_window, CV_WINDOW_NORMAL);
    createTrackbar(trackbar_title, Output_window, &match_method, max_track, Match_Demo);//创建滑动条并进行初始化
    Match_Demo(0, 0);  //参数为0,表示进行一次初始化

    waitKey(0);
    return 0;
}

void Match_Demo(int, void*)  //响应滑动条的回调函数
{
    int height = src.rows - temp.rows + 1;
    int width = src.cols - temp.cols + 1;
    Mat result(width, height, CV_32FC1);

    matchTemplate(src, temp, result, match_method, Mat());//匹配
    normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());//标准化

    Point minLoc;
    Point maxLoc;
    double min, max;

    Mat dst;
    src.copyTo(dst);
    Point tempLoc;
    minMaxLoc(result, &min, &max, &minLoc, &maxLoc,Mat()); //通过函数minMaxLoc定位最匹配的位置
    if (match_method== CV_TM_SQDIFF||match_method==CV_TM_SQDIFF_NORMED) //越小的数值有着更高的匹配结果
    {
        tempLoc = minLoc;
    }
    else  //其余方法,数值越大匹配效果越好
    {
        tempLoc = maxLoc;
    }

    rectangle(dst, Rect(tempLoc.x, tempLoc.y, temp.cols, temp.rows),Scalar(0,0,255),2,8,0);//绘制出矩形,并显示最终结果
    rectangle(result, Rect(tempLoc.x, tempLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8, 0);

    namedWindow("Output window2", CV_WINDOW_NORMAL);
    imshow("Output window2", dst);
    namedWindow(Output_window, CV_WINDOW_NORMAL);
    imshow(Output_window, result);
    return;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值