模板匹配 Match Template 修改版

2021-05-22 20:24:40 字數 4476 閱讀 5719

修改者:madturtle------對於王先生的版本進行了修改,因為有些地方不對。

模板匹配的工作方式

模板匹配的工作方式跟直方圖的反向投影基本一樣,大致過程是這樣的:通過在輸入影象上滑**像塊對實際的影象塊和輸入影象進行匹配。

假設我們有一張100x100的輸入影象,有一張10x10的模板影象,查詢的過程是這樣的:

(1)從輸入影象的左上角(0,0)開始,切割一塊(0,0)至(10,10)的臨時影象;(改者注:其實每次匹配都是在模板的中心點對應的位置來給畫素賦值,即第一次比較應該是將模板的(temp.width/2,temp.height/2)中心點開始的1/4面積同輸入影象進行比較,匹配得到的結果c儲存到模板中心點所在畫素值中,具體參照《learning opencv》,所以最終用來保留匹配結果的影象大小應該是size =  (images->width - patch_size.x + 1,images->height - patch_size.y + 1))

(2)用臨時影象和模板影象進行對比,對比結果記為c;

(3)對比結果c,就是結果影象(0,0)處的畫素值;

(4)切割輸入影象從(0,1)至(10,11)的臨時影象,對比,並記錄到結果影象;

(5)重複(1)~(4)步直到輸入影象的右下角。

大家可以看到,直方圖反向投影對比的是直方圖,而模板匹配對比的是影象的畫素值;模板匹配比直方圖反向投影速度要快一些,但是我個人認為直方圖反向投影的魯棒性會更好。

模板匹配的匹配方式

在opencv和emgucv中支援以下6種對比方式:

cv_tm_sqdiff 平方差匹配法:該方法採用平方差來進行匹配;最好的匹配值為0;匹配越差,匹配值越大。

cv_tm_ccorr 相關匹配法:該方法採用乘法操作;數值越大表明匹配程度越好。

cv_tm_ccoeff 相關係數匹配法:1表示完美的匹配;-1表示最差的匹配。

cv_tm_sqdiff_normed 歸一化平方差匹配法

cv_tm_ccorr_normed 歸一化相關匹配法

cv_tm_ccoeff_normed 歸一化相關係數匹配法

根據我的測試結果來看,上述幾種匹配方式需要的計算時間比較接近(跟《學習opencv》書上說的不同),我們可以選擇乙個能適應場景的匹配方式。

模板匹配的示例**

下面是模板匹配的c#版本**:

//模板匹配

private void btncalc_click(object sender, eventargs e)

//色彩空間

string colorspace = (string)cmbcolorspace.selecteditem;

iimage imageinput2, imagetemplate2;

if (colorspace == "gray")

else if (colorspace == "hsv")

else

//匹配方式陣列

tm_type tmtypes = new tm_type ;

//輸出影象(匹配結果)

image imageresults = new image[tmtypes.length];

//依次執行每種匹配,並歸一化結果

int i = 0;

double totaltime = 0d; //總共用時

double time; //每種匹配的用時

stopwatch sw = new stopwatch();

txtresult.text += string.format("開始執行匹配(色彩空間:,縮放因子:)/r/n", colorspace, scale);

foreach (tm_type tmtype in tmtypes)

,用時:毫秒,最匹配的點:(,),最匹配的值:/r/n", tmtype, time, bestpoint.x, bestpoint.y, bestvalue);

}

txtresult.text += string.format("匹配結束,共用時:毫秒/r/n", totaltime);

//顯示結果影象

pbresultsqdiff.image = imageconverter.imagesingletobitmap(imageresults[0]);

pbresultsqdiffnormalized.image = imageconverter.imagesingletobitmap(imageresults[1]);

pbresultccorr.image = imageconverter.imagesingletobitmap(imageresults[2]);

pbresultccorrnormalized.image = imageconverter.imagesingletobitmap(imageresults[3]);

pbresultccoeff.image = imageconverter.imagesingletobitmap(imageresults[4]);

pbresultccoeffnormalized.image = imageconverter.imagesingletobitmap(imageresults[5]);

//釋放資源

imageinput.dispose();

imagetemplate.dispose();

imageinput2.dispose();

imagetemplate2.dispose();

foreach (imageimageresult in imageresults)

imageresult.dispose();

}

//找到最匹配的點,以及該點的值

private void findbestmatchpointandvalue(imageimage, tm_type tmtype, out double bestvalue, out point bestpoint)

else

}

顯示結果影象模板匹配和直方圖反向投影生成的結果影象都是32位浮點型單通道影象。如果用c/c++,可以很方便的用opencv中的cvshowimage函式來顯示;如果用.net,因為emgucv中將32位浮點影象轉換成8位位圖的方法有些小問題,我們要自己編寫一段轉換的**,然後再顯示。

/// 

/// 將任意浮點型影象轉換成byte影象;

/// 本轉換函式對浮點型影象的具體畫素值沒有要求,自動將值縮放到0~255之間。

///

/// 影象的色彩空間

/// 浮點型影象

/// 返回byte型影象

public static imageimagesingletobyte(imagesource)

where tcolor : struct, icolor

//得到縮放比率和偏移量

double scale = 1.0, shift = 0.0;

scale = (max == min) ? 0.0 : 255.0 / (max - min);

shift = (scale == 0) ? min : -min * scale;

//縮放影象,並浮點影象縮放到256級的灰度

cvinvoke.cvconvertscaleabs(source.ptr, dest.ptr, scale, shift);

return dest;

}

///

/// 將任意浮點型影象轉換成每通道8位的bitmap;

/// 本轉換函式對浮點型影象的具體畫素值沒有要求,自動將值縮放到0~255之間。

///

/// 影象的色彩空間

/// 浮點型影象

/// 返回每通道8位的bitmap

左上是輸入影象,左中是模板影象,右邊是各種匹配方式的結果(相關匹配的結果明顯不正確)

模板匹配和直方圖反向投影的效率

總的來說,模板匹配和直方圖反向投影的效率都不高。在我的機器上,在1136*852大小的輸入影象上匹配104*132的大小的模板影象(都是單通道灰度影象),大約需要700毫秒;而直方圖反向投影大約需要75000毫秒(1.25分鐘)。看來還需要繼續學習,尋找更好的處理方法。

另一方面,通過搜尋opencv的源**,發現opencv基本上沒有使用平行計算。如果學習完之後,還有時間和熱情,我準備嘗試優化下opencv的平行計算;如果.net 4.0正式版推出了,也可以選擇在這一方面做點優化。

OpenCV模板匹配

include include opencv2 opencv.hpp using namespace std using namespace cv int main int argc,char argv load reference image img imread argv 1 always ch...

opencv模板匹配

模板匹配是一種用於在源影象s中尋找定位給定目標影象t 即模板影象 的技術。其原理很簡單,就是通過一些相似度準則來衡量兩個影象塊之間的相似度similarity s,t 2.用途 模板匹配方法常用於一些平面影象處理中,例如印刷中的數字 工業零器件等小尺寸目標影象識別分類。3.方法 模板匹配中,源影象和...

模板匹配opencv

模板匹配,就是在一幅影象中尋找另一幅模板影象最匹配 也就是最相似 的部分的技術。說的有點抽象,下面給個例子說明就很明白了。在上面這幅全明星照中,我們想找出姚明頭像的位置,並把它標記出來,可以做到嗎?可以,這就是模板匹配的要做的事情。其實模板匹配實現的思想也是很簡單很暴力的,就是拿著模板 姚明頭像 在...