博客
关于我
(九)OpenCV Canny边缘检测
阅读量:797 次
发布时间:2023-03-28

本文共 2197 字,大约阅读时间需要 7 分钟。

基础原理

边缘检测是根据灰度突变来分割图像的一种常用方法。边缘模型通常分为台阶模型和斜坡模型。在实际图像中,斜坡边缘模型更为常见。在使用二阶梯度获取图像边缘时,二阶导数会产生一个局部极大正值和一个局部极小负值,这在图像上表现为双线性效应。

Canny边缘检测

Canny边缘检测算法由John F. Canny在1986年提出,主要包括以下步骤:

  • 高斯核平滑图像:使用高斯核对输入图像进行平滑处理,以去除噪声。
  • 计算梯度幅度和方向图:计算图像的梯度幅度和方向,公式分别为: [ M(x, y) = \sqrt{g_x^2(x, y) + g_y^2(x, y)} ] 和 [ \alpha(x, y) = \arctan\left(\frac{g_y(x, y)}{g_x(x, y)}\right) ] 其中,(g_x(x, y)) 和 (g_y(x, y)) 分别表示图像在 x 和 y 方向上的梯度。
  • 非极大值抑制:在一个 3x3 区域内,定义 4 个边缘法线方向(水平、垂直、+45°、-45°),并对梯度幅度进行细化处理。
  • 双阈值处理和连同性分析:使用滞后阈值处理,设置低阈值和高阈值,通过连同性分析检测并连接边缘。
  • OpenCV API

    OpenCV 提供了 cv::Canny 函数来实现上述算法。函数参数说明如下:

    • image:单通道灰度图像。
    • edges:存储边缘像素的输出图像。
    • threshold1threshold2:滞后阈值处理的超参数。
    • apertureSize:使用 Sobel 算子时的卷积核大小,默认为 3。
    • L2gradient:计算梯度幅值时是否使用 L2 范数,默认为 false。

    函数调用示例:

    void cv::Canny(InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false)

    示例

    以下是一个使用 OpenCV 实现 Canny 边缘检测的示例代码:

    #include 
    #include
    #include
    #include
    using namespace std;
    using namespace cv;
    static void CannyThreshold(int, void*) {
    // 对图像进行高斯滤波
    blur(src_gray, detected_edges, Size(3, 3));
    // 应用 Canny 算法
    Canny(detected_edges, detected_edges, low_threshold, low_threshold * ratio, ks);
    // 初始化结果图像
    dst.create(src.size(), src.type());
    // 复制原始图像到结果图像
    src.copyTo(dst, detected_edges);
    // 显示结果图像
    imshow("Canny Edge Map", dst);
    // 保存结果图像
    imwrite("seg_res.png", dst);
    }
    int main(int argc, char **argv) {
    CommandLineParser parser(argc, argv, "{@input | fruits.jpg | input image}");
    src = imread(samples::findFile(parser.get
    ("@input")), IMREAD_COLOR);
    if (src.empty()) {
    cout << "Could not open or find the image!" << endl
    << "Usage: " << argv[0] << "
    " << endl;
    return -1;
    }
    // 初始化结果图像
    dst.create(src.size(), src.type());
    cvtColor(src, src_gray, COLOR_BGR2GRAY);
    namedWindow("Canny Edge Map", WINDOW_AUTOSIZE);
    createTrackbar("Min Threshold:", "Canny Edge Map", &low_threshold, max_low_threshold, CannyThreshold);
    CannyThreshold(0, 0);
    waitKey(0);
    return 0;
    }

    上述代码首先读取输入图像,进行灰度转换后调用 Canny 函数进行边缘检测,并将结果显示和保存。

    转载地址:http://gahfk.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现循环队列算法(附完整源码)
    查看>>
    Objective-C实现循环队列链表算法(附完整源码)
    查看>>
    Objective-C实现快速傅立叶变换FFT算法(附完整源码)
    查看>>
    Objective-C实现快速傅里叶变换FFT(附完整源码)
    查看>>
    Objective-C实现快速傅里叶变换FFT(附完整源码)
    查看>>
    Objective-C实现快速排序(附完整源码)
    查看>>
    Objective-C实现快速排序(附完整源码)
    查看>>
    Objective-C实现快速排序算法(附完整源码)
    查看>>
    Objective-C实现恩尼格玛密码机算法(附完整源码)
    查看>>
    Objective-C实现感知哈希算法(附完整源码)
    查看>>
    Objective-C实现感知哈希算法(附完整源码)
    查看>>
    Objective-C实现截留雨水问题的动态编程方法算法(附完整源码)
    查看>>
    Objective-C实现截留雨水问题的蛮力方法的算法(附完整源码)
    查看>>
    Objective-C实现打印10000以内的完数(附完整源码)
    查看>>
    Objective-C实现打印1000以内的水仙花数(附完整源码)
    查看>>
    Objective-C实现打印九九乘法表(附完整源码)
    查看>>
    Objective-C实现打印从 0 到 n 的卡特兰数算法(附完整源码)
    查看>>
    Objective-C实现打印函数调用堆栈( 附完整源码)
    查看>>
    Objective-C实现打印月份的日历算法(附完整源码)
    查看>>
    Objective-C实现打印杨辉三角(附完整源码)
    查看>>