opencv_ex27-影像模板比對matchTemplate、歸一化函式normalize、計算比對後目標影像的位置minMaxLoc、畫矩形rectangle

opencv_ex27-影像模板比對matchTemplate、歸一化函式normalize、計算比對後目標影像的位置minMaxLoc、畫矩形rectangle

opencv_ex27-影像模板比對matchTemplate、歸一化函式normalize、計算比對後目標影像的位置minMaxLoc、畫矩形rectangle


GITHUB: https://github.com/jash-git/CPP_opencv249_ex


    影像模板比對
        void matchTemplate(InputArray image, InputArray templ, OutputArray result, int method)

        image:輸入圖,必須為 8位元或浮點數圖。
        templ:輸入的template,尺寸必須小於輸入圖,形態需相同。
        result:比較結果圖,必須為單通道32位元浮點數圖,如果image的尺寸為W x H,templ的尺寸為w x h,則result的尺寸為(W-w+1)x(H-h+1)。
        method:比較方法,有以下六種方法可選擇:
            method=CV_TM_SQDIFF
            method=CV_TM_SQDIFF_NORMED
            method=CV_TM_CCORR
            method=CV_TM_CCORR_NORMED
            method=CV_TM_CCOEFF
            method=CV_TM_CCOEFF_NORMED

        當我們的參數為CV_TM_SQDIFF時,計算結果較小時相似度較高,當我們參數為CV_TM_CCORR、CV_TM_CCOEF時,計算結果較大時相似度較高。

    歸一化函式
        normalize(src, dst, alpha, beta, norm_type, dtype, mask)

        src-輸入陣列。

        dst-與SRC大小相同的輸出陣列。

        α-範數值在範圍歸一化的情況下歸一化到較低的範圍邊界。

        β-上限範圍在範圍歸一化的情況下;它不用於範數歸一化。

        正規化-規範化型別(見下面的細節)。
            NORM_MINMAX: 陣列的數值被平移或縮放到一個指定的範圍,線性歸一化。
            NORM_INF: 歸一化陣列的(切比雪夫距離)L∞範數(絕對值的最大值)
            NORM_L1:  歸一化陣列的(曼哈頓距離)L1-範數(絕對值的和)
            NORM_L2: 歸一化陣列的(歐幾里德距離)L2-範數

        dType——當輸出為負時,輸出陣列具有與SRC相同的型別;否則,它具有與SRC相同的通道數和深度=CVH-MatthAsHead(DyType)。

    當我們得到比較圖後,根據由比較方式,選擇比較圖最小或最大值的地方,就是目標影像的位置。
        void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray())

        src:輸入圖。
        minVal:極小值,可輸入NULL表示不需要。
        maxVal :極大值,可輸入NULL表示不需要。
        minLoc:極小值的位置,可輸入NULL表示不需要。
        maxLoc:極大值的位置,可輸入NULL表示不需要。
        mask:可有可無的遮罩。

畫矩形
        void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)

        img:輸入圖,矩形會畫在上面。
        pt1:矩形頂點。
        pt2:矩形頂點,pt1的對角邊
        color:矩形的顏色。
        thickness:矩形的邊線寬度,輸入負值或CV_FILLED代表填滿矩形。
        lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/ml/ml.hpp>

#include <iostream>
#include <cstdio>

#include <sys/timeb.h>
#if defined(WIN32)
    #define  TIMEB    _timeb
    #define  ftime    _ftime
    typedef __int64 TIME_T;
#else
    #define TIMEB timeb
    typedef long long TIME_T;
#endif

using namespace cv;
using namespace std;
Mat src;//input image

void Pause()
{
    printf("Press Enter key to continue...");
    fgetc(stdin);
}

Mat input;
Mat temp;
Mat dst;
int match_method = TM_SQDIFF;
int max_track = 5;
void Match_Demo(int, void*);
int main()
{

	input = imread("input.png");
	if (!input.data)
    {
		printf("could not load image...\n");
	}
    else
    {
        namedWindow("input", CV_WINDOW_AUTOSIZE);
        namedWindow("temp", CV_WINDOW_AUTOSIZE);
        namedWindow("match_output", CV_WINDOW_NORMAL);
        imshow("input", input);
        temp = imread("temp.png");
        imshow("temp", temp);

        const char* trackbar_title = "Match Algo Type:";
        createTrackbar(trackbar_title, "match_output", &match_method, max_track, Match_Demo);
        Match_Demo(0, 0);
    }
    waitKey(0);
    Pause();
    return 0;
}
void Match_Demo(int, void*) {
	int width = input.cols - temp.cols + 1;
	int height = input.rows - temp.rows + 1;
	Mat result(width, height, CV_32FC1);

	/*
    影像模板比對
        void matchTemplate(InputArray image, InputArray templ, OutputArray result, int method)
        image:輸入圖,必須為 8位元或浮點數圖。
        templ:輸入的template,尺寸必須小於輸入圖,形態需相同。
        result:比較結果圖,必須為單通道32位元浮點數圖,如果image的尺寸為W x H,templ的尺寸為w x h,則result的尺寸為(W-w+1)x(H-h+1)。
        method:比較方法,有以下六種方法可選擇:
            method=CV_TM_SQDIFF
            method=CV_TM_SQDIFF_NORMED
            method=CV_TM_CCORR
            method=CV_TM_CCORR_NORMED
            method=CV_TM_CCOEFF
            method=CV_TM_CCOEFF_NORMED
        當我們的參數為CV_TM_SQDIFF時,計算結果較小時相似度較高,當我們參數為CV_TM_CCORR、CV_TM_CCOEF時,計算結果較大時相似度較高。
	*/
	matchTemplate(input, temp, result, match_method);

	/*
    歸一化函式
        normalize(src, dst, alpha, beta, norm_type, dtype, mask)
        src-輸入陣列。
        dst-與SRC大小相同的輸出陣列。
        α-範數值在範圍歸一化的情況下歸一化到較低的範圍邊界。
        β-上限範圍在範圍歸一化的情況下;它不用於範數歸一化。
        正規化-規範化型別(見下面的細節)。
            NORM_MINMAX: 陣列的數值被平移或縮放到一個指定的範圍,線性歸一化。
            NORM_INF: 歸一化陣列的(切比雪夫距離)L∞範數(絕對值的最大值)
            NORM_L1:  歸一化陣列的(曼哈頓距離)L1-範數(絕對值的和)
            NORM_L2: 歸一化陣列的(歐幾里德距離)L2-範數
        dType——當輸出為負時,輸出陣列具有與SRC相同的型別;否則,它具有與SRC相同的通道數和深度=CVH-MatthAsHead(DyType)。
	*/
	normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

	Point minLoc;
	Point maxLoc;
	double min, max;
	input.copyTo(dst);
	Point temLoc;
	/*
    當我們得到比較圖後,根據由比較方式,選擇比較圖最小或最大值的地方,就是目標影像的位置。
        void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray())
        src:輸入圖。
        minVal:極小值,可輸入NULL表示不需要。
        maxVal :極大值,可輸入NULL表示不需要。
        minLoc:極小值的位置,可輸入NULL表示不需要。
        maxLoc:極大值的位置,可輸入NULL表示不需要。
        mask:可有可無的遮罩。
	*/
	minMaxLoc(result, &min, &max, &minLoc, &maxLoc, Mat());

	if (match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED) {
		temLoc = minLoc;
	} else {
		temLoc = maxLoc;
	}

	rectangle(dst, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);

	//rectangle(result, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);
	//imshow("temp", result);

	imshow("match_output", dst);
}

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *