边缘检测算法

本文详细介绍了Canny算子和Sobel算子在图像边缘检测中的应用。Canny算子包括高斯滤波去噪、梯度计算、极大值抑制和双阈值边缘连接四个步骤;Sobel算子则直接通过特定模板计算梯度。文章提供了简单的C代码实现,并展示了实验效果。
摘要由CSDN通过智能技术生成

*Canny算子与Sobel算子求图像边缘笔记*

1、Canny求边缘算法原理简述
Canny检测边缘主要分为以下 四个算法步骤:
A:噪声去除
canny算子是通过对每个像素点求一阶导数来找到梯度明显的边缘,对图像中的噪声很敏感。所以用Canny算子对图像求导前,先用高斯滤波核函数对图像灰度矩阵的每一点进行加权求平均,以平滑图像去除噪声。这里采用
这里写图片描述
的高斯核对图像进行卷积实现高斯滤波。

B:求图像梯度
利用如下图的Canny算子对图像求X,Y方向梯度(数学意义上的X,Y方向的偏导),然后综合X,Y方向梯度计算该点的梯度,及梯度与X轴的夹角。
这里写图片描述

上图是算子,下图是梯度计算公式:

这里写图片描述

C:极大值抑制(代码中未实现)
其实就是找出局部的极大值,将非极大值设为0。

D: 双阈值提取与边缘连接
采用一大一小阈值对梯度图像进行过滤,摄取出两幅边缘图像, 一个边缘噪声少,但有可能损失部分边缘,一个边缘噪声多,但边缘比前者充分。再通过类似求联通区域的方法连接两图像,得到边缘。

C代码实现如下
(这只是一个很粗陋的代码实现,上班之余的小练习,如错误欢迎指正):

{
        /*先高斯滤波*/
        /*求对应像素点四个方向的梯度幅值与方向*/
        /*非极大值抑制*/
        /*双阀值边缘连接*/
        S16 asGaussFilter[E_3x3_KERNEL][E_3x3_KERNEL] = {
  {
  1, 2, 1},
                                                         {
  2, 4, 2},
                                                         {
  1, 2, 1}};
        U8 *pucGaussBuf = pucTmpBuf;

        PU16 pusCnyGrdBuf = (PU16)(pucGaussBuf + usImgStep*usImgHgt*sizeof(U8));    /*梯度大小*/
        PU16 pusCnyCnrBuf = (PU16)(pusCnyGrdBuf + usImgStep*usImgHgt*sizeof(U8));   /*梯度角度*/

        U8 *pucCnyGrdBuf3 = (PU8)(pusCnyCnrBuf) + usImgStep*usImgHgt*sizeof(U16);
        U8 *pucCnyGrdBuf4 =       pucCnyGrdBuf3 + usImgStep*usImgHgt*sizeof(U8);

        U16 *pusCnyStkPosY = (U16 *)(pucCnyGrdBuf4 + usImgStep * usImgHgt * sizeof(U8));
        U16 *pusCnyStkPosX = pusCnyStkPosY + usImgStep * usImgHgt;

        U16 usKnlWth = E_3x3_KERNEL;
        U16 usKnlHgt = E_3x3_KERNEL;

        S16 sThreshCny1 = 20;
        S16 sThreshCny2 = 30;

        U8 ucSrlNum = 1;

        U32 uiStackCnt = 0;

        /*高斯滤波*/
        for ( usYIdx = 0 ; usYIdx < usImgHgt ; usYIdx++ )
        {
            for ( usXIdx = 0 ; usXIdx < usImgWth ; usXIdx++ )
            {
                uiXYIdx = (U32)(usYIdx * usImgStep + usXIdx);

                if( 0 == usXIdx ||
                    0 == usYIdx ||
                    usImgWth - 1 == usXIdx ||
                    usImgHgt - 1 == usYIdx )
                {
                    pucGaussBuf[uiXYIdx] = pucYImgIn[uiXYIdx];
                }
                else
                {
                    U16 usGaussTmpVal = 0;

                    U8 *pucBuf = pucYImgIn + uiXYIdx - usImgStep - 1;

                    for ( usKYIdx = 0 ; usKYIdx < usKnlHgt ; usKYIdx++ )
                    {
                        for ( usKXIdx = 0 ; us
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值