影象處理中的模板匹配c++實現
阿新 • • 發佈:2018-11-23
一、理論基礎
- 基於相關的模板匹配技術可直接用於在一幅影象中,尋找某種子影象模式。對於大小為MxN的影象f(x,y)和大小為JxK的子影象模式w(x,y),f與w的相關可表示為:
其種,x=0,1,2,…N-K,y=0,1,2,…M-J。此處
的目的是尋找匹配而不是對f(x,y)進行濾波操作,因此w的原點被設定在子影象的左上角,
並且式(11-3) 給出的形式也完全適用於J和K 為偶數的情況。計算相關c(x,y)的過程就是在影象f(x,y)中逐點地移動子影象w(x,小),使w 的原點和點
(x,y)重合,然後計算w與f中被w覆蓋的影象區域對應畫素的乘積之和,以此計算結果作
為相關影象c(x,)在(x,y)點的響應。相關可用於在影象f(x,y)中找到與子影象w(x,y)匹配的所有位置。實際上,當w 按照上
段中描述的過程移過整幅影象f之後,最大的響應點(xo,yo)即為最佳匹配的左上角點。我們
也可以設定一個閾值T,認為響應值大於該閾值的點均是可能的匹配位置。- 相關的計算是通過將影象元素和子模式影象元素聯絡起來獲得的,將相關元素相乘後累
加。我們完全可以將子影象w視為一個按行或按列儲存的向量,將計算過程中被w覆蓋的影象區域視為另一個按照同樣的方式儲存的向量.這樣一來,相關計算就- 成了向量之間的點積運算。
兩個向量的點積為:
- 其中,Θ 為向量、之間的夾角。顯然,當
改進的用於匹配的相關計算公式如下:
二、程式碼部分
- 看了腦疼的理論,下面看看讓人愉快的程式碼吧。
TemplateMatch.h
#pragma once
#include<opencv2\opencv.hpp>
using namespace cv;
typedef unsigned char BYTE;
void TemplateMatch(Mat * pTo, Mat * pTemplate,Mat * src);
TemplateMatch.cpp
#include"TemplateMatch.h"
void TemplateMatch(Mat * pTo, Mat * pTemplate, Mat * src)
{
//迴圈變數
int i, j, m, n;
double dSumT; //模板元素的平方和
double dSumS; //影象子區域元素的平方和
double dSumST; //影象子區域和模板的點積
//響應值
double R;
//記錄當前的最大響應
double MaxR;
//最大響應出現位置
int nMaxX;
int nMaxY;
int nHeight = src->rows;
int nWidth = src->cols;
//模板的高、寬
int nTplHeight = pTemplate->rows;
int nTplWidth = pTemplate->cols;
//計算 dSumT
dSumT = 0;
for (m = 0; m < nTplHeight; m++)
{
for (n = 0; n < nTplWidth; n++)
{
// 模板影象第m行,第n個象素的灰度值
int nGray =*pTemplate->ptr(m, n);
dSumT += (double)nGray*nGray;
}
}
//找到影象中最大響應的出現位置
MaxR = 0;
for (i = 0; i < nHeight - nTplHeight + 1; i++)
{
for (j = 0; j < nWidth - nTplWidth + 1; j++)
{
dSumST = 0;
dSumS = 0;
for (m = 0; m < nTplHeight; m++)
{
for (n = 0; n < nTplWidth; n++)
{
// 原影象第i+m行,第j+n列象素的灰度值
int nGraySrc = *src->ptr(i + m, j + n);
// 模板影象第m行,第n個象素的灰度值
int nGrayTpl = *pTemplate->ptr(m, n);
dSumS += (double)nGraySrc*nGraySrc;
dSumST += (double)nGraySrc*nGrayTpl;
}
}
R = dSumST / (sqrt(dSumS)*sqrt(dSumT));//計算相關響應
//與最大相似性比較
if (R > MaxR)
{
MaxR = R;
nMaxX = j;
nMaxY = i;
}
}
}
//將找到的最佳匹配區域複製到目標影象
for (m = 0; m < nTplHeight; m++)
{
for (n = 0; n < nTplWidth; n++)
{
int nGray = *src->ptr(nMaxY + m, nMaxX + n);
//pTo->setTo(nMaxX + n, nMaxY + m, RGB(nGray, nGray, nGray));
pTo->at<BYTE>(nMaxY + m, nMaxX + n) = nGray;
}
}
}
測試程式碼
#include"TemplateMatch.h"
#include<iostream>
using namespace std;
int main()
{
Mat src = imread("./src.jpg", 0);
Mat Template = imread("./template.jpg", 0);
Mat pt=src;
pt.data = new BYTE[src.cols*src.rows];
memset(pt.data, 255, src.cols*src.rows);
TemplateMatch(&pt, &Template, &src);
imshow("S", src);
imshow("T", Template);
imshow("P", pt);
imwrite("S.jpg", src);
imwrite("T.jpg", Template);
imwrite("P.jpg", pt);
waitKey(0);
return 0;
}
效果如下:
下面給出這個工程的百度雲連線:連結:http://pan.baidu.com/s/1jIuuT3w 密碼:veto
寫的不好的地方,還希望指正,O(∩_∩)O謝謝。
在這我要強烈推薦一本書:《數字影象處理與機器視覺 Visual C 與Matlab實現》,這本書寫的很基礎,適合初學者和研究人員