c++实现canny算子(不用OpenCV)
canny算子我看到很多都是介绍原理,实现用OpenCV函数实现。下面我用c++实现了一下canny算子。
原理
原理参考优快云博客,我觉得解释的很好优快云博客
实现
用高斯滤波器平滑图像
void Glbq(BYTE * im, int h, int w, BYTE * om) //用的是灰度图像,0-255,所以用BYTE*
{
int mask[9] = {
1,1,1, ///高斯核
1,8,1,
1,1,1};
BYTE temp[9];//用来存储某个像素点的3*3邻域
int i, j, n, m;
for (i = 0; i < 9;i++)//初始化
{
temp[i]= 0;
}
memcpy(om, im, sizeof(BYTE)*w*h);//把输入图像复制到输出图像
for (i = 1; i < h-1; i++)//在图像的最外一层不进行循环
{
for (j = 1; j < w-1; j++)
{
for (m = -1; m < 2;m++)//选中一块3*3邻域
{
for (n = -1; n < 2;n++)
{
temp[(m+ 1) * 3 + (n + 1)] = im[(i + m)*w + j + n];
}
}
om[i*w + j] =convolution(temp, mask)/16+0.5;//这里调用的是一个卷积函数
}
}
}
卷积
int convolution(BYTE * temp, int * mask)
{
int i, sum{
0};
for (i = 0; i < 9;i++)
{
sum+= temp[i] * mask[i];//3*3的邻域和3*3的模板对应相乘,相加。
}
return sum;
}
实现,包括梯度幅值和方向、非最大值抑制、双阈值连接
void Slbq(BYTE * im, int h, int w, BYTE * om,BYTE* om1)
{
//用sobel算子计算梯度幅值和方向
//下面是sobel算子的实现
int mask[9] = {
-1,0,1, //Sobel算子
-2,0,2,
-1,0,1 };
int mask1[9] = {
1,2,1, //Sobel算子
0,0,0,
-1,-2,-1};
BYTE temp[9];
int i, j, n, m;
for (i = 0; i < 9;i++)
{
temp[i]= 0;
}
double* ymw1 = new double[w*h];
double* ymw2 = new double[w*h];
for (i = 0; i < h*w; i++)
{
ymw1[i]= 0;
ymw2