#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; }
全站熱搜