数组指针pointDirection里存放了每个点上的梯度方向角,以度为单位。由于atan求得的角度范围是-π/2~π/2,为了便于计算,这里对每个梯度角加了一个π/2,使范围变成0~π,便于计算。
X方向梯度图: Y方向梯度图:

2.2 求梯度图的幅
求得X、Y方向的梯度和梯度角之后再来计算X和Y方向融合的梯度幅,计算公式为:
代码实现,较为简单:
//******************计算Sobel的X和Y方向梯度幅值*************************
//第一个参数imageGradX是X方向梯度图像;
//第二个参数imageGradY是Y方向梯度图像;
//第三个参数SobelAmpXY是输出的X、Y方向梯度图像幅值
//*************************************************************
void SobelAmplitude(const Mat imageGradX,const Mat imageGradY,Mat &SobelAmpXY)
{
SobelAmpXY=Mat::zeros(imageGradX.size(),CV_32FC1);
for(int i=0;i<SobelAmpXY.rows;i++)
{
for(int j=0;j<SobelAmpXY.cols;j++)
{
SobelAmpXY.at<float>(i,j)=sqrt(imageGradX.at<uchar>(i,j)*imageGradX.at<uchar>(i,j)+imageGradY.at<uchar>(i,j)*imageGradY.at<uchar>(i,j));
}
}
convertScaleAbs(SobelAmpXY,SobelAmpXY);
}
求得的X和Y方向幅度和叠加了两个方向上的幅:

三、对梯度幅进行非极大抑制
求幅图像进行非极大抑制,可以进一步消除非边缘的噪点,更重要的是,可以细化边缘。
抑制逻辑是:沿着该点梯度方向,比较前后两个点的幅大小,若该点大于前后两点,则保留,若该点小于前后两点,则置为0;
图中四条虚线代表图像中每一点可能的梯度方向,沿着梯度方向与边界的上下两个交点,就是需要拿来与中心点点(X0,Y0)做比较的点。交点的计算采用插法计算,以的虚线所代表的梯度角Θ为例,交点处幅为:
四种情况下需要分别计算,代码实现如下:
//******************局部极大值抑制*************************
//第一个参数imageInput输入的Sobel梯度图像;
//第二个参数imageOutPut是输出的局部极大值抑制图像;
//第三个参数pointDrection是图像上每个点的梯度方向数组指针
//*************************************************************
void LocalMaxValue(const Mat imageInput,Mat &imageOutput,double *pointDrection)
{
//imageInput.copyTo(imageOutput);
imageOutput=imageInput.clone();
int k=0;
for(int i=1;i<imageInput.rows-1;i++)
{
for(int j=1;j<imageInput.cols-1;j++)
{
int value00=imageInput.at<uchar>((i-1),j-1);
int value01=imageInput.at<uchar>((i-1),j);
int value02=imageInput.at<uchar>((i-1),j+1);
int value10=imageInput.at<uchar>((i),j-1);
int value11=imageInput.at<uchar>((i),j);
int value12=imageInput.at<uchar>((i),j+1);
int value20=imageInput.at<uchar>((i+1),j-1);
int value21=imageInput.at<uchar>((i+1),j);
int value22=imageInput.at<uchar>((i+1),j+1);
if(pointDrection[k]>0&&pointDrection[k]<=45)
{
if(value11<=(value12+(value02-value12)*tan(pointDrection[i*imageOutput.rows+j]))||(value11<=(value10+(value20-value10)*tan(pointDrection[i*imageOutput.rows+j]))))
{
imageOutput.at<uchar>(i,j)=0;
}
}
if(pointDrection[k]>45&&pointDrection[k]<=90)
{
if(value11<=(value01+(value02-value01)/tan(pointDrection[i*imageOutput.cols+j]))||value11<=(value21+(value20-value21)/tan(pointDrection[i*imageOutput.cols+j])))
{
imageOutput.at<uchar>(i,j)=0;
}
}
if(pointDrection[k]>90&&pointDrection[k]<=135)
{
if(value11<=(value01+(value00-value01)/tan(180-pointDrection[i*imageOutput.cols+j]))||value11<=(value21+(value22-value21)/tan(180-pointDrection[i*imageOutput.cols+j])))
{
imageOutput.at<uchar>(i,j)=0;
}
}
if(pointDrection[k]>135&&pointDrection[k]<=180)
{
if(value11<=(value10+(value00-value10)*tan(180-pointDrection[i*imageOutput.cols+j]))||value11<=(value12+(value22-value11)*tan(180-pointDrection[i*imageOutput.cols+j])))
{
imageOutput.at<uchar>(i,j)=0;
}
}
k++;
}
}
}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-33925-4.html
对于美国人对我岛礁建设提出的意见对我有利的将坚决采纳
台湾必须无条件接受统一