canny算子

Canny算法通过高斯平滑去噪声,然后利用多个mask检测亮度梯度,结合滞后阈值跟踪边缘,最终得到清晰的边缘图像。该算法包括去噪声、计算梯度、非极大值抑制和双阈值检测等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       Canny 边缘检测算子是John F. Canny于 1986 年开发出来的一个多级边缘检测算法。更为重要的是 Canny 创立了 边缘检测计算理论(Computational theory of edge detection)解释这项技术如何工作。
  Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:
   好的检测 - 算法能够尽可能多地标识出图像中的实际边缘。
   好的定位 - 标识出的边缘要尽可能与实际图像中的实际边缘尽可能接近。
   最小响应 - 图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。

  为了满足这些要求 Canny 使用了变分法,这是一种寻找满足特定功能函数的方法。最优检测使用四个指数函数项的和表示,但是它非常近似于高斯函数的一阶导数

 

 

Canny 算法的步骤

 去噪声

任何边缘检测算法都不可能在未经处理的原始数据上很好地处理,所以第一步是对原始数据与高斯平滑模板作卷积,得到的图像与原始图像相比有些轻微的模糊(blurred)。这样,单独的一个像素噪声在经过高斯平滑的图像上变得几乎没有影响。

寻找图像中的亮度梯度

图像中的边缘可能会指向不同的方向,所以 Canny 算法使用 4 个 mask 检测水平、垂直以及对角线方向的边缘。原始图像与每个 mask 所作的卷积都存储起来。对于每个点我们都标识在这个点上的最大值以及生成的边缘的方向。这样我们就从原始图像生成了图像中每个点亮度梯度图以及亮度梯度的方向。

在图像中跟踪边缘

较高的亮度梯度比较有可能是边缘,但是没有一个确切的值来限定多大的亮度梯度是边缘多大又不是,所以 Canny 使用了滞后阈值。

滞后阈值需要两个阈值——高阈值与低阈值。假设图像中的重要边缘都是连续的曲线,这样我们就可以跟踪给定曲线中模糊的部分,并且避免将没有组成曲线的噪声像素当成边缘。所以我们从一个较大的阈值开始,这将标识出我们比较确信的真实边缘,使用前面导出的方向信息,我们从这些真正的边缘开始在图像中跟踪整个的边缘。在跟踪的时候,我们使用一个较小的阈值,这样就可以跟踪曲线的模糊部分直到我们回到起点。

一旦这个过程完成,我们就得到了一个二值图像,每点表示是否是一个边缘点。

一个获得亚像素精度边缘的改进实现是在梯度方向检测二阶方向导数的过零点

L_x^2 \, L_{xx} + 2 \, L_x \,  L_y \, L_{xy} + L_y^2 \, L_{yy} = 0,

它在梯度方向的三阶方向导数满足符号条件

L_x^3 \, L_{xxx} + 3 \, L_x^2 \, L_y \, L_{xxy} + 3 \, L_x \, L_y^2 \, L_{xyy} + L_y^3 \, L_{yyy} < 0

其中 L_x,L_y ...L_{yyy} 表示用高斯核平滑原始图像得到的尺度空间表示L 计算得到的偏导数。用这种方法得到的边缘片断是连续曲线,这样就不需要另外的边缘跟踪改进。滞后阈值也可以用于亚像素边缘检测。

Canny算法实现:

  1. 用高斯滤波器平滑图像(在调用Canny之前自己用blur平滑)
  2. 用一阶偏导的有限差分来计算梯度的幅值和方向.
  3. 对梯度幅值应用非极大值抑制 .
  4. 用双阈值算法检测和连接边缘.
#include<opencv2/opencv.hpp>

#include <iostream>

using namespace std;
using namespace cv;

Mat src, src_gray;
Mat dst, detected_edges;
int edgeThresh=1;
int lowThreshold;
int const max_lowThreshold=100;
int ratio=3;
int kernel_size=3;
char *window_name="Edge Map";

void CannyThreshold(int , void *)
{
	blur(src_gray,detected_edges, Size(3,3));
	   Canny(detected_edges,detected_edges, lowThreshold, lowThreshold*ratio, kernel_size);
	   dst=Scalar::all(0);
	   src.copyTo(dst,detected_edges);
	   imshow(window_name,dst);


}


int main()
{
	  src=imread("e:\\kankan\\baihe.jpg");
	  if(!src.data)
	  {
		  return -1;
	  }
	  dst.create(src.size(),src.type());
	  cvtColor (src, src_gray, CV_BGR2GRAY);
	  namedWindow(window_name, CV_WINDOW_AUTOSIZE);
	  createTrackbar("Min Threshold", window_name, &lowThreshold, max_lowThreshold, CannyThreshold);
	  CannyThreshold(0,0);
	  waitKey(0);
	  return 0;
}


 

下面是效果图:

 

 

参考文献
[1]贾云德.机器视觉[M].北京:科学出版社,2000
[2]章毓晋.图象处理和分析[M].北京:清华大学出版社,1999
[3]郎锐.数字图象处理学.北京:希望电子出版社,2002
[4]王娜,李霞.一种新的改进Canny边缘检测算法.深圳大学学报,2005,4(2),149-152

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值