OpenCV 边缘检测 Canny源码剖析

OpenCV Canny边缘检测源码注释剖析
本文详细剖析了OpenCV中Canny边缘检测算子的源码,通过注释解释了关键部分的功能,帮助读者理解算法实现细节。

Canny 算子源码见我的下载资源

下面是我对Canny 算子源码部分细节功能的注释,代码详见源码。

void cv::Canny( InputArray _src, OutputArray _dst,
                double low_thresh, double high_thresh,
                int aperture_size, bool L2gradient )
{
    Mat src = _src.getMat();
    CV_Assert( src.depth() == CV_8U );

    _dst.create(src.size(), CV_8U);
    Mat dst = _dst.getMat();

....
//aperture--空隙大小/尺寸
    if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7)))
        CV_Error(CV_StsBadFlag, "");

    if (low_thresh > high_thresh)
        std::swap(low_thresh, high_thresh);

....
//CV_16SC--#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n)),其中CV_16S表示16位短整型,详见types_c.h中

    const int cn = src.channels();
    Mat dx(src.rows, src.cols, CV_16SC(cn));
    Mat dy(src.rows, src.cols, CV_16SC(cn));
//这里两次计算x轴,y轴方向上的像素点的导数估计值并存在dx ,dy 数组中

    Sobel(src, dx, CV_16S, 1, 0, aperture_size, 1, 0, cv::BORDER_REPLICATE);
    Sobel(src, dy, CV_16S, 0, 1, aperture_size, 1, 0, cv::BORDER_REPLICATE);

//L2gradient这里用于指示梯度估计使用的公式
    1-- = \sqrt{(dI/dx)^2 + (dI/dy)^2}
    if (L2gradient)
    0/default-- = |dI/dx|+|dI/dy|

    {
        low_thresh = std::min(32767.0, low_thresh);
        high_thresh = std::min(32767.0, high_thresh);
//平方
        if (low_thresh > 0) low_thresh *= low_thresh;
        if (high_thresh > 0) high_thresh *= high_thresh;
    }
    int low = cvFloor(low_thresh);
    int high = cvFloor(high_thresh);
//这里以及后面对行,列扩展2表示图像边缘扩展

    ptrdiff_t mapstep = src.cols + 2;
    AutoBuffer<uchar> buffer((src.cols+2)*(src.rows+2) + cn * mapstep * 3 * sizeof(int));

//初始化图像中三行数据,并分配存储空间
    int* mag_buf[3];
 
### OpenCV Canny 边缘检测的使用方法 Canny边缘检测是一种经典的边缘检测算法,在计算机视觉领域应用广泛。以下是关于如何使用OpenCV库中的`cv2.Canny()`函数进行Canny边缘检测的具体说明。 #### 基本原理概述 Canny边缘检测的核心在于通过一系列步骤提取图像中的显著边缘[^1]。这些步骤包括但不限于高斯滤波降噪、梯度计算、非极大值抑制以及双阈值检测和边缘连接。这种多阶段的方法使得Canny算法能够在保持良好检测性能的同时减少误检率[^4]。 #### `cv2.Canny()` 函数介绍 在OpenCV中,可以通过调用`cv2.Canny()`函数轻松实现Canny边缘检测。此函数的主要参数及其作用如下: - **image**: 输入图像,通常为灰度图像。 - **threshold1**: 第一阈值,较低阈值,用于控制弱边界的识别。 - **threshold2**: 第二阈值,较高阈值,用于控制强边界的识别。 - **apertureSize (可选)**: Sobel算子使用的孔径大小,默认为3。 - **L2gradient (可选)**: 如果设置为True,则使用更精确但较慢的L2范数来计算梯度幅值;默认为False[^2]。 #### 实现代码示例 下面是一个完整的Python代码示例,展示如何利用OpenCV进行Canny边缘检测: ```python import cv2 import numpy as np from matplotlib import pyplot as plt # 加载原始图像并转换为灰度图 img = cv2.imread('example.jpg', 0) # 应用GaussianBlur平滑处理以降低噪声影响 blurred_img = cv2.GaussianBlur(img, (5, 5), 0) # 调用Canny函数进行边缘检测 edges = cv2.Canny(blurred_img, threshold1=50, threshold2=150) # 显示原图与边缘检测结果 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 Detection Result'), plt.xticks([]), plt.yticks([]) plt.show() ``` 上述代码展示了从加载图像到最终显示边缘检测结果的整体流程。其中,`cv2.GaussianBlur()`函数用于预处理输入图像以去除噪声干扰,这对于提高后续Canny算法的效果至关重要[^5]。 #### 注意事项 为了获得更好的效果,建议调整`threshold1`和`threshold2`两个参数值,具体数值的选择取决于应用场景及目标特征的需求。此外,对于彩色图像,应先将其转化为灰度模式再执行Canny操作[^3]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值