OpenCV中的模板匹配/Filter2d
1、模板匹配
??? 模板匹配是在圖像中尋找目標(biāo)的方法之一。Come On, Boy.我們一起來看看模板匹配到底是怎么回事。
??? 參考鏈接:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/histograms/template_matching/template_matching.html
??????????????????? http://www.cnblogs.com/xrwang/archive/2010/02/05/MatchTemplate.html
模板匹配的工作方式
??? 模板匹配的工作方式跟直方圖的反向投影基本一樣,大致過程是這樣的:通過在輸入圖像上滑動圖像塊對實(shí)際的圖像塊和輸入圖像進(jìn)行匹配。
??? 假設(shè)我們有一張100x100的輸入圖像,有一張10x10的模板圖像,查找的過程是這樣的:
? (1)從輸入圖像的左上角(0,0)開始,切割一塊(0,0)至(10,10)的臨時圖像;
? (2)用臨時圖像和模板圖像進(jìn)行對比,對比結(jié)果記為c;
? (3)對比結(jié)果c,就是結(jié)果圖像(0,0)處的像素值;
? (4)切割輸入圖像從(0,1)至(10,11)的臨時圖像,對比,并記錄到結(jié)果圖像;
? (5)重復(fù)(1)~(4)步直到輸入圖像的右下角。
??? 大家可以看到,直方圖反向投影對比的是直方圖,而模板匹配對比的是圖像的像素值;模板匹配比直方圖反向投影速度要快一些,但是我個人認(rèn)為直方圖反向投影的魯棒性會更好。
?
模板匹配的匹配方式
??? 在OpenCv和EmguCv中支持以下6種對比方式:
??? CV_TM_SQDIFF?平方差匹配法:該方法采用平方差來進(jìn)行匹配;最好的匹配值為0;匹配越差,匹配值越大。
??? CV_TM_CCORR?相關(guān)匹配法:該方法采用乘法操作;數(shù)值越大表明匹配程度越好。
??? CV_TM_CCOEFF?相關(guān)系數(shù)匹配法:1表示完美的匹配;-1表示最差的匹配。
??? CV_TM_SQDIFF_NORMED?歸一化平方差匹配法
??? CV_TM_CCORR_NORMED?歸一化相關(guān)匹配法
??? CV_TM_CCOEFF_NORMED?歸一化相關(guān)系數(shù)匹配法
??? 根據(jù)我的測試結(jié)果來看,上述幾種匹配方式需要的計算時間比較接近(跟《學(xué)習(xí)OpenCv》書上說的不同),我們可以選擇一個能適應(yīng)場景的匹配方式。
?
顯示結(jié)果圖像??? 模板匹配和直方圖反向投影生成的結(jié)果圖像都是32位浮點(diǎn)型單通道圖像
模板匹配和直方圖反向投影的效率
??? 總的來說,模板匹配和直方圖反向投影的效率都不高。在我的機(jī)器上,在1136*852大小的輸入圖像上匹配104*132的大小的模板圖像(都是單通道灰度圖像),大約需要700毫秒;而直方圖反向投影大約需要75000毫秒(1.25分鐘)。看來還需要繼續(xù)學(xué)習(xí),尋找更好的處理方法。
??? 另一方面,通過搜索OpenCv的源代碼,發(fā)現(xiàn)OpenCv基本上沒有使用并行計算。如果學(xué)習(xí)完之后,還有時間和熱情,我準(zhǔn)備嘗試優(yōu)化下OpenCv的并行計算;如果.net 4.0正式版推出了,也可以選擇在這一方面做點(diǎn)優(yōu)化。
代碼:
// 用于存儲匹配結(jié)果的矩陣 cv::Mat result;int result_cols = minM.cols - tempMat.cols + 1; int result_rows = minM.rows - tempMat.rows + 1; result.create( result_cols, result_rows, CV_32FC1 ); // 進(jìn)行模板匹配 int match_method = CV_TM_SQDIFF;cv::matchTemplate( MatSrc, tempMat, result, match_method ); // 歸一化結(jié)果(方便顯示結(jié)果) //cv::normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() ); // 找到最佳匹配位置 double minVal =0; double maxVal =0; cv::Point minLoc(0,0); cv::Point maxLoc(0,0); cv::Point matchLoc(0,0); cv::Point matchCenter(0,0); cv::Point matchSrc(0,0); cv::minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() ); // 尋找result中的最大和最小值,以及它們所處的像素位置// 使用SQDIFF和SQDIFF_NORMED方法時:值越小代表越相似 // 使用其他方法時:值越大代表越相似 if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED ) { matchLoc = minLoc; } else { matchLoc = maxLoc; }
2、Filter2d
OpenCv Filter2d進(jìn)行二維卷積進(jìn)行的是相關(guān)運(yùn)算;
參考鏈接:http://blog.csdn.net/superdont/article/details/6662365
高通和低通濾波
#include "cv.h" #include "highgui.h"int main(int argc,char**argv) { IplImage* src, *dst, src_f; float low[9] ={ 1.0/16, 2.0/16, 1.0/16, 2.0/16, 4.0/16, 2.0/16, 1.0/16, 2.0/16, 1.0/16 };//低通濾波核float high[9]={-1,-1,-1,-1,9,-1,-1,-1,-1};//高通濾波核CvMat km = cvMat( 3, 3, CV_32FC1, low); //構(gòu)造單通道浮點(diǎn)矩陣,將圖像IplImage結(jié)構(gòu)轉(zhuǎn)換為圖像數(shù)組 src = cvLoadImage( "lena.jpg" ); st = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 3 );cvFilter2D( src, dst, &km, cvPoint( -1, -1 ) ); //設(shè)參考點(diǎn)為核的中心cvNamedWindow( "src", 0 );cvNamedWindow( "filtering", 0 );cvShowImage( "src", src ); cvShowImage( "filtering", dst ); cvWaitKey(0); cvReleaseImage( &src ); cvReleaseImage( &dst ); return 0; } ??
3、通過傅里葉變換求圖像卷積
參考鏈接:http://blog.csdn.net/lichengyu/article/details/18848281
各種濾波(平滑、銳化)的情況,基本方法都是將圖像與一個核進(jìn)行卷積實(shí)現(xiàn)。而卷積定理指出,兩個函數(shù)的卷積的傅里葉變換等于各自的傅里葉變換的乘積,即:
[1]
那么,兩個函數(shù)的卷積可以通過如下方式得到,對兩個函數(shù)傅里葉變換的乘積做傅里葉反變換,即:
[1]
在進(jìn)行卷積運(yùn)算時,一般是將核沿著圖像從左到右從上到下計算每一個像素處與核卷積后的值,這樣的計算量較大,采用傅里葉變換的方法可以提高運(yùn)算效率。
............................................代碼見原文章.....
需要注意的是,一般求法中,利用核游走整個圖像進(jìn)行卷積運(yùn)算,實(shí)際上進(jìn)行的是相關(guān)運(yùn)算,真正意義上的卷積,應(yīng)該首先把核翻轉(zhuǎn)180度,再在整個圖像上進(jìn)行游走。OpenCV中的filter2D實(shí)際上做的也只是相關(guān),而非卷積。"The function does actually compute correlation, not the convolution: ... That is, the kernel is not mirrored around the anchor point. If you need a real convolution, flip the kernel using flip() and set the new anchor to (kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1)
總結(jié)
以上是生活随笔為你收集整理的OpenCV中的模板匹配/Filter2d的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阴阳师玉林狼魂十一要求
- 下一篇: 图像连通域检测的2路算法Code