杭州品牌網(wǎng)站開發(fā)東莞網(wǎng)站推廣的公司
圖像模板匹配原理
? ? ?例如給定一張圖片,如上圖大矩陣所示,然后給定一張模板圖像,如上圖小矩陣。
? ? ?我們?cè)诖髨D像中去搜索與小圖像中相同的部分或者是最為相似的內(nèi)容。比如我們?cè)趫D像中以灰色區(qū)域給出一個(gè)與模板圖像尺寸大小一致的區(qū)域,通過比較灰色區(qū)域中的內(nèi)容與模板中的內(nèi)容,兩者如果一致,那么則認(rèn)定兩者是相似的,從而實(shí)現(xiàn)了在目標(biāo)圖像中尋找模板圖像的匹配過程,若兩者不一致,比如上圖陰影區(qū)域中第一個(gè)像素值為3,而模板中第一個(gè)像素值為4,那么兩者之間存在差距,通過每一個(gè)對(duì)應(yīng)像素之間進(jìn)行一次度量計(jì)算作為模板匹配中的匹配系數(shù)(度量矩陣),之后移動(dòng)圖像中的陰影區(qū)域(一次移動(dòng)一個(gè)像素,從左往右,從上往下),再次對(duì)陰影區(qū)域所對(duì)應(yīng)的像素值與模板中的像素進(jìn)行度量計(jì)算得到模板匹配系數(shù),每移動(dòng)一次陰影區(qū)域就可以得到一個(gè)模板匹配系數(shù),之后尋找這個(gè)系數(shù)所代表的匹配的最佳結(jié)果的位置即為最終的匹配結(jié)果(相似程度最高)。
? ? 如上圖所示用TM_CCORR_NORMED方法處理后的result為度量矩陣(即匹配系數(shù)),最白的位置代表最高的匹配系數(shù),以系數(shù)最佳(最大或者最小,看你用什么算法)為頂點(diǎn)(即圖像的左上角點(diǎn),opencv中圖像坐標(biāo)原點(diǎn)為左上角點(diǎn),y向下值越大,x向右值越大),做一個(gè)長(zhǎng)寬和模板圖像一樣大小的矩形框,即為最佳匹配的區(qū)域。
實(shí)際中我們可以使用函數(shù)minMaxLoc來定位矩陣R中的最大值(最小值)。
圖像模板匹配函數(shù)
matchTenplate()
vodi cv::matchTemplate(InputArray image,InputArray templ,OutputArray result,int method,InputArray mask = noArray())
·image:待模板匹配的原圖像,圖像數(shù)據(jù)類型為CV_8U和CV_32F兩者之一。
·templ:模板圖像,需要與image具有相同的數(shù)據(jù)類型,但是尺寸不能大于image。
·result:模板匹配結(jié)果輸出圖像,圖像數(shù)據(jù)類型為CV_32F。如果image的尺寸為W*H,模板圖像尺寸為w*h,則輸出圖像的尺寸為(W-w+1) * (H-h+1)。
·method:模板匹配方法標(biāo)志。
·mask:匹配模板的掩碼,必須與模板圖像具有相同的數(shù)據(jù)類型和尺寸,默認(rèn)情況下不設(shè)置,目前僅支持在TM_SQDIFF和TM_CCORR_NORMED這兩種匹配方法時(shí)使用。
圖像模板匹配方法標(biāo)志
·平方差匹配TM_SQDIFF:
最好匹配為0,匹配程度越低,值越大。
·標(biāo)準(zhǔn)平方差匹配TM_SQDIFF_NORMED:
·相關(guān)匹配TM_CCORR:
此類方法采用模板與圖像間的乘法操作,所以較大的數(shù)表示匹配程度高,0表示最差的匹配效果。
·標(biāo)準(zhǔn)相關(guān)匹配TM_CCORR_NORMED:
·系數(shù)匹配TM_CCOEFF:
此類方法將模板對(duì)其均值的相對(duì)值與圖像對(duì)其均值的相對(duì)值進(jìn)行匹配,1表示完美匹配,-1表示糟糕匹配,0表示沒有任何相關(guān)性(隨機(jī)序列)。
·標(biāo)準(zhǔn)系數(shù)匹配:TM_CCOEFF_NORMED:
隨著從簡(jiǎn)單的測(cè)量(平方差)到更復(fù)雜的測(cè)量(相關(guān)系數(shù)),我們可獲得越來越準(zhǔn)確的匹配(也意味著越來越大的計(jì)算代價(jià)),最好的辦法是對(duì)所有這些設(shè)置多做一些測(cè)試實(shí)驗(yàn),以便為自己的應(yīng)用選擇同時(shí)兼顧速度和精度的最佳方案。
示例:
#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv; //opencv的命名空間
using namespace std;//主函數(shù)
int main()
{Mat img = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/lenac.png");Mat temp = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/lena_face.png");//模板圖像Mat result; //匹配結(jié)果matchTemplate(img, temp, result, TM_CCOEFF_NORMED);//模板匹配函數(shù)double maxval, minval;Point maxLoc, minLoc;minMaxLoc(result, &minval, &maxval, &minLoc, &maxLoc);//最大值最小值尋找函數(shù)//然后我們?cè)趫D像中找到最大值的位置,繪制出匹配成功的區(qū)域,就能夠在圖像中看到最佳匹配的結(jié)果rectangle(img, Point(maxLoc.x, maxLoc.y), Point(maxLoc.x + temp.cols, maxLoc.y + temp.rows), Scalar(0, 0, 255), 2);//矩形框繪制
circle(img, Point(maxLoc.x, maxLoc.y), 1, Scalar(255, 0, 120), 30); //最大值點(diǎn)的位置imshow("原圖像", img);imshow("模板圖像", temp);imshow("result", result);waitKey(0);//等待函數(shù)用于顯示圖像return 0;}