int main()
{
// 读取原始图片
Mat image1= cv::imread("lena.jpg",0);
namedWindow("lena");
imshow("lena",image1);
// 定义3X3Gauss模板
Mat mask=(Mat_<char>(3,3)<<1/16,2/16,1/16,
2/16,4/16,2/16,
1/16,2/16,1/16);
// Gauss模板对原始图片卷积
Mat image2;
filter2D(image1,image2,image1.depth (),mask);
// 一阶有限差分近似计算梯度的幅值和方向
int P[512][512];
int Q[512][512];
double M[512][512];
double a[512][512];
for(int j=0;j<image2.rows;j++)
{
for(int i=0;j<image2.cols;i++)
{
P[j][i]=(image2.at<char>(j,i+1)-image2.at<char>(j,i)+image2.at<char>(j+1,i+1)-image2.at<char>(j+1,i))/2;
Q[j][i]=(image2.at<char>(j,i)-image2.at<char>(j+1,i)+image2.at<char>(j,i+1)-image2.at<char>(j+1,i+1))/2;
M[j][i]= sqrt((double)(P[j][i]*P[j][i]+Q[j][i]*Q[j][i]));
a[j][i]= atan2((double)Q[j][i],(double)P[j][i]);
}
}
// 非极大值抑制
for(int j=0;j<image2.rows;j++)
{
for(int i=0;j<image2.cols;i++)
{
if((a[j][i]>=-1/8*PI&&a[j][i]<1/8*PI)||(a[j][i]>=7/8*PI&&a[j][i]<PI)||(a[j][i]<-7/8*PI&&a[j][i]>=-PI))
a[j][i]=0;
else if((a[j][i]>=1/8*PI&&a[j][i]<3/8*PI)||(a[j][i]>=-7/8*PI&&a[j][i]<-5/8*PI))
a[j][i]=1;
else if((a[j][i]>=3/8*PI&&a[j][i]<5/8*PI)||(a[j][i]>=-5/8*PI&&a[j][i]<-3/8*PI))
a[j][i]=2;
else
a[j][i]=3;
}
}
for(int j=0;j<image2.rows;j++)
{
for(int i=0;j<image2.cols;i++)
{
if(a[j][i]==0)
{
if(image2.at<char>(j,i)<image2.at<char>(j,i-1)||image2.at<char>(j,i)<image2.at<char>(j,i+1))
image2.at<char>(j,i)=0;
}
else if(a[j][i]==1)
{
if(image2.at<char>(j,i)<image2.at<char>(j-1,i+1)||image2.at<char>(j,i)<image2.at<char>(j+1,i-1))
image2.at<char>(j,i)=0;
}
else if(a[j][i]==2)
{
if(image2.at<char>(j,i)<image2.at<char>(j-1,i)||image2.at<char>(j,i)<image2.at<char>(j+1,i))
image2.at<char>(j,i)=0;
}
else
if(image2.at<char>(j,i)<image2.at<char>(j-1,i-1)||image2.at<char>(j,i)<image2.at<char>(j+1,i+1))
image2.at<char>(j,i)=0;
}
}
namedWindow("非极大值抑制");
imshow("非极大值抑制",image2);
waitKey(100000000);
return 0;
}