本文**
背景概述
opencv中自帶的模板匹配演算法,完全是畫素基本的模板匹配,特別容易受到光照影響,光照稍微有所不同,該方法就會歇菜了!搞得很多opencv初學者剛學習到該方法時候很開心,一用該方法馬上很傷心,悲喜交加,充分感受到了理想與現實的距離,不過沒關係,這裡介紹一種新的模板匹配演算法,主要是基於影象邊緣梯度,它對影象光照與畫素遷移都有很強的抗干擾能力,據說halcon的模板匹配就是基於此的加速版本,在工業應用場景中已經得到廣泛使用。
演算法原理
該演算法主要是基於影象梯度,實現基於梯度級別的ncc模板匹配,基於sobel梯度運算元得到dx, dy, magnitude
通過canny演算法得到邊緣影象、基於輪廓發現得到所有的輪廓點集,基於每個點計算該點的dx、dy、magnitude(dxy)三個值。生成模板資訊。然後對輸入的影象進行sobel梯度影象之後,根據模型資訊進行匹配,這樣的好處有兩個:
演算法實現**詳解
梯度影象計算
mat gx, gy;
sobel(gray, gx, cv_32f, 1, 0);
sobel(gray, gy, cv_32f, 0, 1);
mat magnitude, direction;
carttopolar(gx, gy, magnitude, direction);
long contourslength = 0;
double magnitudetemp = 0;
int originx = contours[ 0][ 0].x;
int originy = contours[ 0][ 0].y;
模板生成
// 提取dxdymaglog資訊
vector> contoursinfo;
// 提取相對座標位置
vector> contoursrelative;
// 開始提取
for(int i = 0; i < contours.size(); i++) {
int n = contours[i].size();
contourslength += n;
contoursinfo.push_back(vector(n));
vectorpoints(n);
for(int j = 0; j < n; j++) {
int x = contours[i][j].x;
int y = contours[i][j].y;
points[j].x = x - originx;
points[j].y = y - originy;
ptin pointinfo;
pointinfo.derivativex = gx.at(y, x);
pointinfo.derivativey = gy.at(y, x);
magnitudetemp = magnitude.at(y, x);
pointinfo.magnitude = magnitudetemp;
if(magnitudetemp != 0)
pointinfo.magnituden = 1/ magnitudetemp;
contoursinfo[i][j] = pointinfo;
contoursrelative.push_back(points);
計算目標影象梯度
// 計算目標影象梯度
mat grayimage;
cvtcolor(src, grayimage, color_bgr2gray);
mat gradx, grady;
sobel(grayimage, gradx, cv_32f, 1, 0);
sobel(grayimage, grady, cv_32f, 0, 1);
mat mag, angle;
carttopolar(gradx, grady, mag, angle);
ncc模板匹配
double partialscore = 0;
double resultscore = 0;
int resultx = 0;
int resulty = 0;
double start = (double)gettickcount();
for(int row = 0; row < grayimage.rows; row++) {
for(int col = 0; col < grayimage.cols; col++) {
double sum = 0;
long num = 0;
for(int m = 0; m < contoursrelative.size(); m++) {
for(int n = 0; n < contoursrelative[m].size(); n++) {
num += 1;
int curx = col + contoursrelative[m][n].x;
int cury = row + contoursrelative[m][n].y;
if(curx grayimage.cols - 1|| cury > grayimage.rows - 1) {
continue;
// 目標邊緣梯度
double sdx = gradx.at(cury, curx);
double sdy = grady.at(cury, curx);
// 模板邊緣梯度
double tdx = contoursinfo[m][n].derivativex;
double tdy = contoursinfo[m][n].derivativey;
// 計算匹配
if((sdy != 0|| sdx != 0) && (tdx != 0|| tdy != 0))
double nmagnitude = mag.at(cury, curx);
if(nmagnitude != 0)
sum += (sdx * tdx + sdy * tdy) * contoursinfo[m][n].magnituden / nmagnitude;
// 任意節點score之和必須大於最小閾值
partialscore = sum / num;
if(partialscore < min((minscore - 1) + (ngreediness * num), nminscore * num))
break;
// 儲存匹配起始點
if(partialscore > resultscore)
resultscore = partialscore;
resultx = col;
resulty = row;
執行效果
正常光照
光照非常暗
改進:不需要全域性匹配,可以對目標影象先做乙個小梯度閾值,然後再進行匹配,提公升速度、構造目標影象金字塔,實現多解析度模板匹配支援!
opencv模板匹配加速思路
對於工業應用來說,往往需要用到形狀匹配來達到定位功能,visionpro的patmax演算法,halcon的形狀匹配演算法都是基於邊緣的模版匹配。halcon中的形狀匹配具有良好的魯棒性,穩定,準確,快速的特點。opencv中雖然也有形狀匹配演算法,但是,是基於七階不變矩來計算輪廓相似度,具有旋轉縮...
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.方法 模板匹配中,源影象和...