【OpenCV 4开发详解】图像模板匹配
| 經過幾個月的努力,小白終于完成了市面上第一本OpenCV 4入門書籍《OpenCV 4開發詳解》。為了更讓小伙伴更早的了解最新版的OpenCV 4,小白與出版社溝通,提前在公眾號上連載部分內容,請持續關注小白。 |
前面我們通過圖像直方圖反向投影的方式在圖像中尋找模板圖像,由于直方圖不能直接反應圖像的紋理,因此如果兩張不同模板圖像具有相同的直方圖分布特性,那么在同一張圖中對這兩張模板圖像的直方圖進行反向投影,最終結果將不具有參考意義。因此,我們在圖像中尋找模板圖像時,可以直接通過比較圖像像素的形式來搜索是否存在相同的內容,這種通過比較像素灰度值來尋找相同內容的方法叫做圖像的模板匹配。
模板匹配常用于在一幅圖像中尋找特定內容的任務中。由于模板圖像的尺寸小于待匹配圖像的尺寸,同時又需要比較兩張圖像中的每一個像素的灰度值,因此常采用在待匹配圖像中選擇與模板相同尺寸的滑動窗口,通過比較滑動窗口與模板的相似程度,判斷待匹配圖像中是否含有與模板圖像相同的內容,其原理如圖4-11所示。
圖4-11 模板匹配示意圖在圖4-11中,右側4×4的圖像是模板圖像,每個像素中的數字是該像素的灰度值,左側8×8圖像是待匹配圖像,模板匹配的流程如下:
- Step1:在待匹配圖像中選取與模板尺寸大小相同的滑動窗口,如圖4-11中的陰影區域所示。
- Step2:比較滑動窗口中每個像素與模板中對應像素灰度值的關系,計算模板與滑動窗口的相似性。
- Step3:將滑動窗口從左上角開始先向右滑動,滑動到最右邊后向下滑動一行,從最左側重新開始滑動,記錄每一次移動后計算的模板與滑動窗口的相似性。
- Step4:比較所有位置的相似性,選擇相似性最大的滑動窗口作為備選匹配結果。
OpenCV 4中提供了用于圖像模板匹配的函數matchTemplate(),該函數能夠實現模板匹配過程中圖像與模板相似性的計算,在代碼清單4-12中給出了函數原型。
代碼清單4-12 matchTemplate()函數原型 1. void cv::matchTemplate(InputArray image, 2. InputArray templ, 3. OutputArray result, 4. int method, 5. InputArray mask = noArray() 6. )- image:待模板匹配的原圖像,圖像數據類型為CV_8U和CV_32F兩者中的一個。
- templ:模板圖像,需要與image具有相同的數據類型,但是尺寸不能大于image。
- result:模板匹配結果輸出圖像,圖像數據類型為CV_32F。如果image的尺寸為W×H,模板圖像尺寸為w×h,則輸出圖像的尺寸為(W-w+1)×(H-h+1)。
- method:模板匹配方法標志,可選擇參數及含義在表4-3中給出。
- mask:匹配模板的掩碼,必須與模板圖像具有相同的數據類型和尺寸,默認情況下不設置,目前僅支持在TM_SQDIFF和TM_CCORR_NORMED這兩種匹配方法時使用。
該函數同時支持灰度圖像和彩色圖像兩種圖像的模板匹配。函數前兩個參數為輸入的原圖像和模板圖像,由于是在原圖像中搜索是否存在與模板圖像相同的內容,因此需要模板圖像的尺寸小于原圖像,并且兩者必須具有相同的數據類型。第三個參數為相似性矩陣,滑動窗口與模板的相似性系數存放在滑動窗口左上角第一個像素處,因此輸出的相似性矩陣尺寸要小于原圖像的尺寸,如果image的尺寸為W×H,模板圖像尺寸為w×h,則輸出圖像的尺寸為(W-w+1)×(H-h+1)。因為在模板匹配中原圖像不需要進行尺寸的外延,所以滑動窗口左上角可以移動的范圍要小于原圖像的尺寸。無論輸入的是彩色圖像還是灰度圖像,函數輸出結果都是單通道矩陣。了解相似性系數記錄的方式便于尋找到與模板最相似的滑動窗口,繼而在原圖中標記出與模板相同的位置。函數第四個參數是滑動窗口與模板相似性系數的計算方式,OpenCV 4提供了多種計算方法,所有可以選擇的標志參數在表4-3中給出,接下來對每一種方法進行詳細介紹。
表4-3 matchTemplate()函數模板匹配方法選擇標志參數| TM_SQDIFF | 0 | 平方差匹配法 |
| TM_SQDIFF_NORMED | 1 | 歸一化平方差匹配法 |
| TM_CCORR | 2 | 相關匹配法 |
| TM_CCORR_NORMED | 3 | 歸一化相關匹配法 |
| TM_CCOEFF | 4 | 系數匹配法 |
| TM_CCOEFF_NORMED | 5 | 歸一化相關系數匹配法 |
(1)TM_SQDIFF:
該方法名為平方差匹配法,計算的公式如式(6.9)所示,這種方法利用平方差來進行匹配,當模板與滑動窗口完全匹配時計算數值為0,兩者匹配度越低計算數值越大。
R(x,y)=∑x′,y′(T(x′,y′)?I(x+x′,y+y′))2(6.9)R(x,y) = \sum\limits_{x',y'} {{{(T(x',y') - I(x + x',y + y'))}^2}} \tag{6.9}R(x,y)=x′,y′∑?(T(x′,y′)?I(x+x′,y+y′))2(6.9)
其中 表示模板圖像, 表示原圖像。
(2)TM_SQDIFF_NORMED:
該方法名為歸一化平方差匹配方法,計算公式如式(6.10)所示,這種方法是將平方差方法進行歸一化,使得輸入結果縮放到了0到1之間,當模板與滑動窗口完全匹配時計算數值為0,兩者匹配度越低計算數值越大。
R(x,y)=∑x′,y′(T(x′,y′)?I(x+x′,y+y′))2∑x′,y′T(x′,y′)2?∑x′,y′I(x+x′,y+y′)2(6.10)R(x,y) = \frac{{\sum\limits_{x',y'} {{{(T(x',y') - I(x + x',y + y'))}^2}} }}{{\sqrt {\sum\limits_{x',y'} {T{{(x',y')}^2}} * \sum\limits_{x',y'} {I{{(x + x',y + y')}^2}} } }} \tag{6.10}R(x,y)=x′,y′∑?T(x′,y′)2?x′,y′∑?I(x+x′,y+y′)2?x′,y′∑?(T(x′,y′)?I(x+x′,y+y′))2?(6.10)
(3)TM_CCORR:
該方法名為相關匹配法,計算公式如式(6.11)所示,這類方法采用模板和圖像間的乘法操作,所以數值越大表示匹配效果越好,0表示最壞的匹配結果。
R(x,y)=∑x′,y′(T(x′,y′)?I(x+x′,y+y′))(6.11)R(x,y) = \sum\limits_{x',y'} {(T(x',y') * I(x + x',y + y'))} \tag{6.11}R(x,y)=x′,y′∑?(T(x′,y′)?I(x+x′,y+y′))(6.11)
(4)TM_CCORR_NORMED:
該方法名為歸一化相關匹配法,計算公式如式(6.12)所示,這種方法是將相關匹配法進行歸一化,使得輸入結果縮放到了0到1之間,當模板與滑動窗口完全匹配時計算數值為1,兩者完全不匹配時計算結果為0。
R(x,y)=∑x′,y′(T(x′,y′)?I(x+x′,y+y′))2∑x′,y′T(x′,y′)2?∑x′,y′I(x+x′,y+y′)2(6.12)R(x,y) = \frac{{\sum\limits_{x',y'} {{{(T(x',y') * I(x + x',y + y'))}^2}} }}{{\sqrt {\sum\limits_{x',y'} {T{{(x',y')}^2}} * \sum\limits_{x',y'} {I{{(x + x',y + y')}^2}} } }} \tag{6.12}R(x,y)=x′,y′∑?T(x′,y′)2?x′,y′∑?I(x+x′,y+y′)2?x′,y′∑?(T(x′,y′)?I(x+x′,y+y′))2?(6.12)
(5)TM_CCOEFF:
該方法名為系數匹配法,計算公式如式(6.13)所示,這種方法采用相關匹配方法對模板減去均值的結果和原圖像減去均值的結果進行匹配,這種方法可以很好的解決模板圖像和原圖像之間由于亮度不同而產生的影響。該方法中模板與滑動窗口匹配度越高計算數值越大,匹配度越低計算數值越小,并且該方法計算結果可以為負數。
R(x,y)=∑x′,y′(T′(x′,y′)?I′(x+x′,y+y′))(6.13)R(x,y) = \sum\limits_{x',y'} {(T'(x',y') * I'(x + x',y + y'))} \tag{6.13}R(x,y)=x′,y′∑?(T′(x′,y′)?I′(x+x′,y+y′))(6.13)
其中:
{T′(x′,y′)=T(x′,y′)?1w?h∑x′′,y′′T(x′′,y′′)I′(x+x′,y+y′)=I(x+x′,y+y′)?1w?h∑x′′,y′′I(x+x′′,y+y′′)(6.14)\left\{ {\begin{matrix} {T'(x',y') = T(x',y') - \frac{1}{{w * h}}\sum\limits_{x'',y''} {T(x'',y'')} }\\ {I'(x + x',y + y') = I(x + x',y + y') - \frac{1}{{w * h}}\sum\limits_{x'',y''} {I(x + x'',y + y'')} } \end{matrix}} \right. \tag{6.14}????T′(x′,y′)=T(x′,y′)?w?h1?x′′,y′′∑?T(x′′,y′′)I′(x+x′,y+y′)=I(x+x′,y+y′)?w?h1?x′′,y′′∑?I(x+x′′,y+y′′)?(6.14)
(6)TM_CCOEFF_NORMED:
該方法名為歸一化系數匹配法,計算公式如式(6.15)所示,這種方法將系數匹配方法進行歸一化,使得輸入結果縮放到了1到-1之間,當模板與滑動窗口完全匹配時計算數值為1,當兩者完全不匹配時計算結果為-1。
R(x,y)=∑x′,y′(T′(x′,y′)?I′(x+x′,y+y′))∑x′,y′T(x′,y′)2?∑x′,y′I′(x+x′,y+y′)2(6.15)R(x,y) = \frac{{\sum\limits_{x',y'} {(T'(x',y') * I'(x + x',y + y'))} }}{{\sqrt {\sum\limits_{x',y'} {T{{(x',y')}^2} * \sum\limits_{x',y'} {I'{{(x + x',y + y')}^2}} } } }} \tag{6.15}R(x,y)=x′,y′∑?T(x′,y′)2?x′,y′∑?I′(x+x′,y+y′)2?x′,y′∑?(T′(x′,y′)?I′(x+x′,y+y′))?(6.15)
了解不同的計算相似性方法時,重點需要知道在每種方法中最佳匹配結果的數值應該是較大值還是較小值,由于matchTemplate()函數的輸出結果是存有相關性系數的矩陣,因此需要通過minMaxLoc()函數去尋找輸入矩陣中的最大值或者最小值,進而確定模板匹配的結果。
通過尋找輸出矩陣的最大值或者最小值得到的只是一個像素點,需要以該像素點為矩形區域的左上角,繪制與模板圖像同尺寸的矩形框,標記出最終匹配的結果。為了了解圖像模板匹配相關函數的使用方法,在代碼清單4-13中給出了在彩色圖像中進行模板匹配的示例程序。程序中采用TM_CCOEFF_NORMED方法計算相關性系數,通過minMaxLoc()函數尋找相關性系數中的最大值,確定最佳匹配值的像素點坐標,之后在原圖中繪制出與模板最佳匹配區域的范圍,程序的運行結果在圖4-12中給出。
代碼清單4-13 myMatchTemplate.cpp圖像的模板匹配 1. #include <opencv2\opencv.hpp> 2. #include <iostream> 3. 4. using namespace cv; 5. using namespace std; 6. 7. int main() 8. { 9. Mat img = imread("lena.png"); 10. Mat temp = imread("lena_face.png"); 11. if (img.empty() || temp.empty()) 12. { 13. cout << "請確認圖像文件名稱是否正確" << endl; 14. return -1; 15. } 16. Mat result; 17. matchTemplate(img, temp, result, TM_CCOEFF_NORMED);//模板匹配 18. double maxVal, minVal; 19. Point minLoc, maxLoc; 20. //尋找匹配結果中的最大值和最小值以及坐標位置 21. minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc); 22. //繪制最佳匹配區域 23. rectangle(img,cv::Rect(maxLoc.x,maxLoc.y,temp.cols,temp.rows),Scalar(0,0,255),2); 24. imshow("原圖", img); 25. imshow("模板圖像", temp); 26. imshow("result", result); 27. waitKey(0); 28. return 0; 29. } 圖4-12 myMatchTemplate.cpp程序運行結果?
| OpenCV 4開發詳解 |
| 【OpenCV 4開發詳解】安裝過程中問題解決方案 |
| 【OpenCV 4開發詳解】了解OpenCV的模塊架構 |
| 【OpenCV 4開發詳解】Mat類介紹 |
| 【OpenCV 4開發詳解】Mat類構造與賦值 |
| 【OpenCV 4開發詳解】4種讀取Mat類元素的的方法 |
| 【OpenCV 4開發詳解】圖像的讀取與顯示 |
| 【OpenCV 4開發詳解】視頻加載與攝像頭調用 |
| 【OpenCV 4開發詳解】圖像與視頻的保存 |
| 【OpenCV 4開發詳解】保存和讀取XML和YMAL文件 |
| 【OpenCV 4開發詳解】顏色模型與轉換 |
| 【OpenCV 4開發詳解】多通道分離與合并 |
| 【OpenCV 4開發詳解】圖像像素統計 |
| 【OpenCV 4開發詳解】兩圖像間的像素操作 |
| 【OpenCV 4開發詳解】圖像二值化 |
| 【OpenCV 4開發詳解】圖像LUT查找表 |
| 【OpenCV 4開發詳解】圖像連接 |
| 【OpenCV 4開發詳解】圖像仿射變換 |
| 【OpenCV 4開發詳解】圖像透視變換 |
| 【OpenCV 4開發詳解】圖像極坐標變換 |
| 【OpenCV 4開發詳解】圖像上繪制幾何圖形 |
| 【OpenCV 4開發詳解】圖像金字塔 |
| 【OpenCV 4開發詳解】窗口交互操作 |
| 【OpenCV 4開發詳解】圖像直方圖繪制 |
| 【OpenCV 4開發詳解】直方圖操作 |
| 【OpenCV 4開發詳解】直方圖應用 |
| 經過幾個月的努力,市面上第一本OpenCV 4入門書籍《OpenCV 4開發詳解》將春節后由人民郵電出版社發行。如果小伙伴覺得內容有幫助,希望到時候多多支持! |
| 關注小白的小伙伴可以提前看到書中的內容,我們創建了學習交流群,歡迎各位小伙伴添加小白微信加入交流群,添加小白時請備注“學習OpenCV 4”。 |
總結
以上是生活随笔為你收集整理的【OpenCV 4开发详解】图像模板匹配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VS2019编译GDAL2.2.4
- 下一篇: Openldap2.5.13编译安装