边缘检测——cvCanny算子

本文介绍了一种使用Canny算法进行图像边缘检测的方法,并通过具体的C++代码实现了从加载图像到显示边缘检测结果的全过程。文章重点展示了如何利用OpenCV库函数cvCanny来处理图像并提取其边缘特征。

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

//创建时间2015年5月27日
//使用到的函数原型:
//      1、 IplImage* cvLoadImage( const char* filename, int flags=CV_LOAD_IMAGE_COLOR );
//      2、 void cvCanny( const CvArr* image,CvArr* edges,double threshold1,double threshold2, int aperture_size=3 );
//收获:cvReleaseImage( &m_PEdgePic );使用的时候参数是一个地址值。
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"


using namespace std;


#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") 


int main()
{
const char * m_PicName="华山论剑.jpg";
const char * m_SavePicName="华山论剑_边缘.jpg";


IplImage *m_PPic=cvLoadImage( m_PicName , CV_LOAD_IMAGE_GRAYSCALE ); //按灰度图像载入
if ( m_PPic == 0 )
{
cout<<"图片载入失败!"<<endl;
return -1;
}
IplImage *m_PEdgePic = NULL;
m_PEdgePic = cvCreateImage( cvGetSize(m_PPic) , m_PPic->depth , m_PPic->nChannels );


cvCanny( m_PPic , m_PEdgePic , 50 , 150 , 3 );
cvSaveImage ( m_SavePicName , m_PEdgePic );  


cvNamedWindow( m_PicName );
cvShowImage( m_PicName , m_PEdgePic );
cvWaitKey( 0 );
cvDestroyWindow( m_PicName );
cvReleaseImage( &m_PEdgePic );


return 0;
}
### Canny算子边缘检测算法原理 Canny算子是一种经典的边缘检测算法,由John F. Canny于1986年提出[^2]。该算法通过优化三个标准设计而成:良好的检测性能、精确的位置定位以及单一的响应特性。其核心目标是从图像中提取有意义的边界信息。 #### 算法的主要步骤 1. **高斯平滑滤波** 为了减少噪声对后续计算的影响,在执行边缘检测之前通常会对输入图像进行高斯平滑处理。这一过程利用高斯卷积核对图像进行加权平均操作,从而降低高频噪声干扰[^3]。推荐使用的卷积核大小为 \(3 \times 3\) 或 \(5 \times 5\)。 2. **梯度幅值和方向计算** 使用一阶偏导数模板(如Sobel算子)分别计算水平和垂直方向上的梯度分量 \(G_x\) 和 \(G_y\)。随后根据这两个分量可以得到梯度幅值和方向: \[ G = \sqrt{G_x^2 + G_y^2} \] 方向角可以通过下式求得: \[ \theta = \arctan\left(\frac{G_y}{G_x}\right) \] 3. **非极大值抑制** 这一步旨在细化边缘,仅保留局部最大值作为候选边缘点。具体而言,对于每一个像素点,比较它与其沿梯度方向的两个相邻点之间的关系。如果当前点不是局部极值,则将其置零[^1]。 4. **双阈值检测与滞后连接** 设置高低两道阈值用于区分强弱边缘点。高于高阈值的被认为是可靠的强边缘;低于低阈值则被舍弃;介于两者之间者需进一步判断是否属于真实边缘的一部分——即是否存在相连的强边缘支持它们的存在。 #### 基于OpenCV实现Canny算子 以下是使用Python结合OpenCV库完成Canny边缘检测的一个简单例子: ```python import cv2 import numpy as np from matplotlib import pyplot as plt # 加载原始图像并转换成灰度图 img = cv2.imread('image.jpg', 0) # 应用Canny函数 edges = cv2.Canny(img, 100, 200) plt.subplot(121), plt.imshow(img, cmap='gray') plt.title('Original Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(edges, cmap='gray') plt.title('Edge Image'), plt.xticks([]), plt.yticks([]) plt.show() ``` 上述代码片段展示了如何加载一张图片并通过调用`cv2.Canny()`方法来进行基本的边缘检测。其中参数\( (100, 200) \)代表设定好的高低阈值范围。 ### 总结 综上所述,Canny算子因其优秀的综合表现成为众多领域内的首选工具之一。尽管存在一定的复杂性和计算成本,但在实际应用当中依然占据重要地位。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值