OpenCV模板匹配函數matchTemplate詳解


參考文檔:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/histograms/template_matching/template_matching.html#id2

 

最近一直在做一個logo檢測的項目,檢測logo的有無,接觸到模板匹配。模板匹配雖然精度不高,但選擇恰當的方法,設置合適的閾值也能起到一定作用。有的時候我們還能用模板匹配來定位。下面對模板匹配進行一個總結。

 

模板匹配:模板匹配是一項在一幅圖像中尋找與另一幅模板圖像最匹配(相似)部分的技術.

 

matchTemplate()參數詳解

CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
                                 OutputArray result, int method );

 

image:待匹配的源圖像
templ:模板圖像
result:保存結果的矩陣,我們可以通過minMaxLoc() 確定結果矩陣的最大值和最小值的位置.
  minMaxLoc()函數:查找全局最小和最大稀疏數組元素並返回其值及其位置
  void minMaxLoc(const SparseMat& a, double* minVal,double* maxVal, int* minIdx=0, int* maxIdx=0);
  • a: 匹配結果矩陣
  • &minVal&maxVal: 在矩陣 result 中存儲的最小值和最大值
  • &minLoc&maxLoc: 在結果矩陣中最小值和最大值的坐標.

method :模板匹配的算法
  有以下六種:
  enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 };
  • TM_SQDIFF,TM_SQDIFF_NORMED匹配數值越低表示匹配效果越好,其它四種反之。
  • TM_SQDIFF_NORMED,TM_CCORR_NORMED,TM_CCOEFF_NORMED是標准化的匹配,得到的最大值,最小值范圍在0~1之間,其它則需要自己對結果矩陣歸一化。
  • 不同的方法會得到差異很大的結果,可以通過測試選擇最合適的方法。

歸一化函數normalize()

normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

 

模板匹配的大致用法如下:

void templateMatching(const Mat& srcImage,const Mat& templateImage)
{
    Mat result;
    int result_cols = srcImage.cols - templateImage.cols + 1;
    int result_rows = srcImage.rows - templateImage.rows + 1;
    if(result_cols < 0 || result_rows < 0)
    {
        qDebug() << "Please input correct image!";
        return;
    }
    result.create(result_cols, result_rows, CV_32FC1);
//    enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 };
    matchTemplate(srcImage,templateImage,result,TM_CCOEFF_NORMED);   //最好匹配為1,值越小匹配越差
    double minVal = -1;
    double maxVal;
    Point minLoc;
    Point maxLoc;
    Point matchLoc;
    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

 //取大值(視匹配方法而定)
//    matchLoc = minLoc;
    matchLoc = maxLoc;

    //取大值,值越小表示越匹配
    QString str = "Similarity:" + QString::number((maxVal) * 100, 'f', 2) + "%";
    qDebug(str.toAscii().data());

    Mat mask = srcImage.clone();
//繪制最匹配的區域 rectangle(mask, matchLoc, Point(matchLoc.x
+ templateImage.cols, matchLoc.y + templateImage.rows), Scalar(0, 255, 0), 2, 8, 0); imshow("mask",mask); }

 

分別采用兩個不同顏色的模板圖進行測試,得到如下兩組結果圖,以供參考。

測試結果1:

 

                       

 

                       

 測試結果2:

 

                   

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM