參考自:https://www.codeproject.com/articles/99457/edge-based-template-matching
實現具體步驟就不介紹:
別人的代碼是opencv老版本實現的,自己看着比較費勁,後面就想着自己重新實現一下,順便熟悉下具體的整個步驟。利用晚上的時間斷斷續續好多天了,今天晚上終於調試完成了。
別人的代碼就不貼了,當時是花人民幣在某寶找人在CSDN下載的。
自己的代碼:
1.梯度和方向計算:
Mat gx, gy;
Sobel(grayTemplateImg, gx, CV_32F, 1, 0, 3);
Sobel(grayTemplateImg, gy, CV_32F, 0, 1, 3);
//計算梯度幅值和梯度方向
Mat magnitude, direction;
cartToPolar(gx, gy, magnitude, direction,true);
當時嘗試定義其他數據類型的時候程序崩潰了,程序中基本都用的CV_32F類型。
2.極大值抑制
for (int r = 1; r< gx.rows-1; r++)
{
for (int c = 1; c < gx.cols-1; c++)
{
float angle = direction.at<float>(r, c);
float mag = magnitude.at<float>(r, c);
float left=0, right=0;
if ((angle>0 && angle<22.5 )|| (angle >157.5 && angle < 202.5) || (angle>337.5 && angle<360))
{
left = magnitude.at<float>(r, c - 1);
right = magnitude.at<float>(r, c + 1);
}
else if ((angle>22.5 && angle < 67.5) || (angle> 202.5 && angle < 247.5))
{
left = magnitude.at<float>(r - 1, c + 1);
right = magnitude.at<float>(r + 1, c - 1);
}
else if ((angle > 67.5 && angle < 112.5) || (angle > 247.5 && angle< 292.5))
{
left = magnitude.at<float>(r - 1, c);
right = magnitude.at<float>(r + 1,c);
}
else if ((angle > 112.5 && angle < 157.5) || (angle > 292.5 && angle < 337.5))
{
left = magnitude.at<float>(r - 1, c-1);
right = magnitude.at<float>(r + 1, c+1);
}
else
{
left = magnitude.at<float>(r, c - 1);
right = magnitude.at<float>(r, c + 1);
}
if (mag < left || mag < right)
edgeMag_noMaxSup.at<float>(r, c) = 0;
else
edgeMag_noMaxSup.at<float>(r, c) = (uchar)(mag / MaxMag * 255);
}
}
3.雙閾值法抑制假邊緣
for (int i = 1; i < gx.rows - 1; i++)
{
for (int j = 1; j < gx.cols; j++)
{
MagG = magnitude.at<float>(i, j);
DirG = direction.at<float>(i, j);
NonMag = edgeMag_noMaxSup.at<float>(i, j);
flag = 1;
if (NonMag <maxContrast)
{
if (NonMag< minContrast)
{
edgeMag_noMaxSup.at<float>(i, j) = 0;
flag = 0;
}
else
{ // if any of 8 neighboring pixel is not greater than max contraxt remove from edge
if (((double)(edgeMag_noMaxSup.at<float>(i - 1,j - 1)) < maxContrast) &&
((double)(edgeMag_noMaxSup.at<float>(i - 1,j)) < maxContrast) &&
((double)(edgeMag_noMaxSup.at<float>(i - 1,j + 1)) < maxContrast) &&
((double)(edgeMag_noMaxSup.at<float>(i,j - 1)) < maxContrast) &&
((double)(edgeMag_noMaxSup.at<float>(i,j + 1)) < maxContrast) &&
((double)(edgeMag_noMaxSup.at<float>(i + 1,j - 1)) < maxContrast) &&
((double)(edgeMag_noMaxSup.at<float>(i + 1,j)) < maxContrast) &&
(double)(edgeMag_noMaxSup.at<float>(i + 1,j + 1)) < maxContrast)
{
edgeMag_noMaxSup.at<float>(i, j) = 0;
flag = 0;
////((uchar*)(imgGDir->imageData + imgGDir->widthStep*i))[j]=0;
}
}
}
}
感覺整個過程就是Canny檢測算法的過程,特別類似。
貼代碼太煎熬了。
還是直接上傳代碼吧。
資源剛上傳,還沒法貼下載地址。
地址:https://download.csdn.net/download/liyuqian199695/12432345
是實現的完整代碼,不是可以編譯可運行的工程,謝謝。不喜勿噴!!!