#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/// 宣告全域變數
Mat img; Mat templ; Mat result;
const char* image_window = "Source Image";
const char* result_window = "Result window";
int match_method;
// 拉桿最大值
int max_Trackbar = 5;
/// 宣告函式
void MatchingMethod(int, void*);
int main(int argc, char ** argv){
/// 載入圖檔
img = imread("C:\\images\\lena.jpg", 1);
imshow("Lena", img);
// 載入範本
templ = imread("C:\\images\\crop-lena.jpg", 1);
imshow("Crop-Lena", templ);
/// 建立視窗
namedWindow(image_window, WINDOW_AUTOSIZE);
namedWindow(result_window, WINDOW_AUTOSIZE);
/// 建立拉桿
// 0: SQDIFF 1: SQDIFF NORMED 2: TM CCORR
// 3: TM CCORR NORMED 4: TM COEFF 5: TM COEFF NORMED
const char* trackbar_label = "Method: ";
createTrackbar(trackbar_label, image_window,
&match_method, max_Trackbar, MatchingMethod);
// 比對
MatchingMethod(0, 0);
waitKey(0);
return 0;
}
// 因為要傳參數但又用不到
void MatchingMethod(int, void*)
{
/// 複製原圖
Mat img_display;
img.copyTo(img_display);
/// 建立結果矩陣
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
result.create(result_cols, result_rows, CV_32FC1);
/// 執行比對與正規化
matchTemplate(img, templ, result, match_method);
normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
double minVal, maxVal;
Point minLoc, maxLoc, matchLoc;
/// 尋找圖中最大與最小的位置
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
/// 用 SQDIFF 與 SQDIFF_NORMED是越低值比較結果越好
/// 其它方法是越高越好試
if (match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED)
{
matchLoc = minLoc;
}
else
{
matchLoc = maxLoc;
}
// 繪比對結果範圍
// 原圖
rectangle(img_display, matchLoc,
Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows),
Scalar::all(0), 2, 8, 0);
// 正規化結果
rectangle(result, matchLoc,
Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows),
Scalar::all(0), 2, 8, 0);
/// 顯示結果
imshow(image_window, img_display);
imshow(result_window, result);
return;
}