目錄
1.模板匹配的定義
2.API介紹
3.尋找最優(yōu)匹配位置(匹配后的配套操作)
4.具體代碼
1.模板匹配的定義
????????模板匹配就是在整個(gè)圖像區(qū)域發(fā)現(xiàn)與給定子圖像匹配的小塊區(qū)域,該匹配方法并不是基于直方圖,而是使用一個(gè)圖像塊在輸入圖像上進(jìn)行“”滑動(dòng)“”。(也就是在圖像上按照模板大小一塊一塊比對(duì))
2.API介紹
void cv::matchTemplate(
cv::InputArray image //需要匹配的圖像
cv::InputArray temp //模板圖像
cv::OutArray result //存儲(chǔ)的計(jì)算得到的結(jié)果
int method //匹配的方法
)
對(duì)于該算子需要注意的有兩點(diǎn):
1.result是存儲(chǔ)匹配的結(jié)果,對(duì)于它的定義為單通道的大小為(image.width-temp.width+1,image.height-temp.height+1),也就是原圖的大小裁去temple模板的寬高,不過(guò)其定義rows和cols需要交換位置(正常圖像Mat定義先rows后cols),同時(shí)數(shù)據(jù)類型可以是CV_8UC1或者CV_32FC1。具體定義如下:
Mat result(image.cols-temp.cols+1,image.rows-temp.rows+1,CV_32FC1)
2.匹配方法介紹
cv::TM_SQDIFF==0(方差匹配法)
cv::TM_SQDIFF_NORMED==1(歸一方差匹配法)
cv::TM_CCORR==2(相關(guān)性匹配方法)
cv::TM_CCORR_NORMED==3(歸一化的互相關(guān)匹配法)
cv::TM_CCOEFF==4(相關(guān)系數(shù)匹配法)
cv::TM_CCOEFF_NORMED==5(歸一化相關(guān)系數(shù)匹配方法)
對(duì)于前兩種方差匹配方法0和1,完全匹配后值為0,不匹配值很大(值越小,匹配效果越好)。
對(duì)于中間兩種相關(guān)匹配方法2和3,完全匹配后值很大,不匹配時(shí)值很小,接近于0。(值越大,匹配效果越好)。
對(duì)于最后兩種相關(guān)系數(shù)匹配方法4和5,完全匹配會(huì)得到1,完全誤匹配會(huì)得到-1。(分值介于-1-1,值越大,匹配效果越好)。
3.尋找最優(yōu)匹配位置(匹配后的配套操作)
1.cv::normalize 歸一化,在同樣的代碼中選擇不同的匹配方法,其result值的結(jié)果也不一致,通過(guò)歸一化算子中cv::NORM_MINMAX方向可以將各點(diǎn)的匹配結(jié)果線性映射到0-1之間。
2.cv::minMaxLoc()最小和最大點(diǎn)查找,通過(guò)該算子可以將result中結(jié)果進(jìn)行查找,找到分?jǐn)?shù)最小最大值和其在result中的位置。
4.具體代碼
#include<iostream>
#include<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
using namespace std;
using namespace cv;
#define WINDOW_NAME1 "【原始圖片】"
#define WINDOW_NAME2 "【效果窗口】"
//定義全局變量
Mat g_srcImage, g_templateImage, g_resultImage;
int g_nMatchmethod;
int g_nMatTrackbarNum = 5;
//定義全局函數(shù)
void on_Matching(int, void*);
int main(int argc,char** argv)
{
//【1】載入原圖像和模塊板
g_srcImage = imread("E:\\進(jìn)度\\11-16\\模板匹配\\1.jpg",1);
g_templateImage = imread("E:\\進(jìn)度\\11-16\\模板匹配\\2.jpg",1);
//【2】創(chuàng)建窗口
namedWindow(WINDOW_NAME1,WINDOW_AUTOSIZE);
namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
//【3】創(chuàng)建滑動(dòng)條并進(jìn)行初始化
createTrackbar("方法",WINDOW_NAME1,&g_nMatchmethod,g_nMatTrackbarNum,on_Matching);
on_Matching(0,0);
waitKey(0);
return 0;
}
//回調(diào)函數(shù)
void on_Matching(int, void*)
{
//【1】 給局部變量初始化
Mat srcImage;
g_srcImage.copyTo(srcImage);
//【2】初始化用于結(jié)果輸出的矩陣
int resultImage_cols = g_srcImage.cols - g_templateImage.cols + 1;
int resultImage_rows = g_srcImage.rows - g_templateImage.rows + 1;
g_resultImage.create(resultImage_cols,resultImage_rows,CV_32FC1);
//【3】進(jìn)行模板匹配
matchTemplate(g_srcImage,g_templateImage,g_resultImage,g_nMatchmethod);
normalize(g_resultImage,g_resultImage,0,1,NORM_MINMAX);
//【4】通過(guò)函數(shù)minMaxLoc 定位最匹配的位置
double minvalue, maxValue;
Point minLocation, maxLocation, MatLocation;
minMaxLoc(g_resultImage,&minvalue,&maxValue,&minLocation,&maxLocation);
//【5】對(duì)于方法SQDIFF和SQDIFF_NORMED越小值有著更高的匹配結(jié)果,而其余的方法,數(shù)值越大匹配效果越好。
if (g_nMatchmethod == TM_SQDIFF || g_nMatchmethod == TM_SQDIFF_NORMED)
{
MatLocation = minLocation;
}
else
{
MatLocation = maxLocation;
}
//【6】繪制出矩陣,并顯示最終結(jié)果
rectangle(srcImage, MatLocation, Point(MatLocation.x + g_templateImage.cols, MatLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 16);
rectangle(g_resultImage, MatLocation, Point(MatLocation.x + g_templateImage.cols, MatLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 16);
imshow(WINDOW_NAME1,srcImage);
imshow(WINDOW_NAME2,g_resultImage);
}
運(yùn)行結(jié)果如下圖:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-478681.html
通過(guò)對(duì)匹配方法的各個(gè)結(jié)果對(duì)比發(fā)現(xiàn),歸一化的匹配方法(2和3)在大多數(shù)情況下都會(huì)有好的結(jié)果,特別是室外環(huán)境的圖像。相關(guān)系數(shù)方法的匹配效果更好,但是計(jì)算時(shí)間代價(jià)高。在實(shí)際的應(yīng)用中,尤其是通過(guò)攝像頭進(jìn)行自動(dòng)部件的檢測(cè)或者特征跟蹤,應(yīng)該嘗試使用所有的方法,從中找到一個(gè)同時(shí)兼顧效率和準(zhǔn)確率的方法。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-478681.html
到了這里,關(guān)于Opencv (C++)系列學(xué)習(xí)---模板匹配的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!