参考自: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
是实现的完整代码,不是可以编译可运行的工程,谢谢。不喜勿喷!!!