OpenCV 如何实现边缘检测器

这篇具有很好参考价值的文章主要介绍了OpenCV 如何实现边缘检测器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

返回:OpenCV系列文章目录(持续更新中......)

上一篇:OpenCV如何实现拉普拉斯算子的离散模拟
下一篇 :OpenCV系列文章目录(持续更新中......)

OpenCV 如何实现边缘检测器,OpenCV,人工智能,C/C++,opencv,人工智能,计算机视觉

目标

在本教程中,您将学习如何:

  • 使用 OpenCV 函数 cv::Canny 实现 Canny 边缘检测器。

理论

Canny Edge探测器[48]由John F. Canny于1986年开发。Canny 算法也被许多人称为最佳检测器,旨在满足三个主要标准:

  • 低错误率:这意味着仅对现有边缘的良好检测。
  • 良好的本地化:必须最小化检测到的边缘像素与实际边缘像素之间的距离。
  • 最小响应:每个边沿只有一个检测器响应。

步骤

  1. 过滤掉任何噪音。高斯滤波器用于此目的。可能使用的(size = 5)高斯核示例如下所示:

OpenCV 如何实现边缘检测器,OpenCV,人工智能,C/C++,opencv,人工智能,计算机视觉

  1. 找到图像的强度渐变。为此,我们遵循类似于 Sobel 的过程:

 a).应用一对卷积掩码在 x 和y 方向上:

 OpenCV 如何实现边缘检测器,OpenCV,人工智能,C/C++,opencv,人工智能,计算机视觉

​编辑 

 b).通过以下方式找到梯度强度和方向::

OpenCV 如何实现边缘检测器,OpenCV,人工智能,C/C++,opencv,人工智能,计算机视觉

​编辑

  1. 方向四舍五入为四个可能的角度之一(即 0、45、90 或 135)
  2. 应用非最大抑制。这将删除不被视为边的一部分的像素。因此,将只保留细线(候选边)。
  3. 滞后:最后一步。Canny 确实使用两个阈值(上限和下限):

    1. 如果像素渐变高于上限阈值,则该像素被接受为边缘
    2. 如果像素渐变值低于限阈值,则将拒绝该值。
    3. 如果像素渐变介于两个阈值之间,则仅当它连接到高于上限阈值的像素时,才会被接受。

    Canny 建议在 2:1 和 3:1 之间使用上比例。

  4. 有关更多详细信息,您可以随时查阅您最喜欢的计算机视觉书籍。

1、C++代码演示:

  • 教程代码如下所示。您也可以从这里下载
    #include "opencv2/imgproc.hpp"
    #include "opencv2/highgui.hpp"
    #include <iostream>
     
    using namespace cv;
     
    Mat src, src_gray;
    Mat dst, detected_edges;
     
    int lowThreshold = 0;
    const int max_lowThreshold = 100;
    const int ratio = 3;
    const int kernel_size = 3;
    const char* window_name = "Edge Map";
     
    static 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( int argc, char** argv )
    {
     CommandLineParser parser( argc, argv, "{@input | fruits.jpg | input image}" );
     src = imread( samples::findFile( parser.get<String>( "@input" ) ), IMREAD_COLOR ); // Load an image
     
     if( src.empty() )
     {
     std::cout << "Could not open or find the image!\n" << std::endl;
     std::cout << "Usage: " << argv[0] << " <Input image>" << std::endl;
     return -1;
     }
     
     dst.create( src.size(), src.type() );
     
     cvtColor( src, src_gray, COLOR_BGR2GRAY );
     
     namedWindow( window_name, WINDOW_AUTOSIZE );
     
     createTrackbar( "Min Threshold:", window_name, &lowThreshold, max_lowThreshold, CannyThreshold );
     
     CannyThreshold(0, 0);
     
     waitKey(0);
     
     return 0;
    }
  • 这个程序是做什么的?
    • 要求用户输入一个数值来设置我们的 Canny Edge Detector 的下限阈值(通过跟踪栏)。
    • 应用 Canny Detector 并生成蒙版(亮线表示黑色背景上的边缘)。
    • 应用在原始图像上获取的蒙版并将其显示在窗口中。

 创建一些需要的变量:

 2、说明(C++ 代码)

Mat src, src_gray;
Mat dst, detected_edges;
 
int lowThreshold = 0;
const int max_lowThreshold = 100;
const int ratio = 3;
const int kernel_size = 3;
const char* window_name = "Edge Map";
  1. 请注意以下事项:

    1. 我们建立了 3:1 的下限:上限阈值(具有可变比率)。
    2. 我们将内核大小设置为 (用于由 Canny 函数在内部执行的 Sobel 操作)。3
    3. 我们为 的下限阈值设置了最大值。100
  2. 加载源图像:
 CommandLineParser parser( argc, argv, "{@input | fruits.jpg | input image}" );
 src = i mread( samples::findFile( parser.get<String>( "@input" ) ), IMREAD_COLOR ); // Load an image
 
 if( src.empty() )
 {
 std::cout << "Could not open or find the image!\n" << std::endl;
 std::cout << "Usage: " << argv[0] << " <Input image>" << std::endl;
 return -1;
 }
  1. 创建一个与 src 类型和大小相同的矩阵(待 dst):
     dst.create( src.size(), src.type() );
  2. 将图像转换为灰度(使用函数 cv::cvtColor ):
     cvtColor( src, src_gray, COLOR_BGR2GRAY );
  3. 创建一个窗口来显示结果:
     namedWindow( window_name, WINDOW_AUTOSIZE );
  4. 为用户创建一个跟踪栏,以输入我们的 Canny 检测器的下限:
     createTrackbar( "Min Threshold:", window_name, &lowThreshold, max_lowThreshold, CannyThreshold );
  5. 请注意以下事项:
    1. 要由 Trackbar 控制的变量是 lowThreshold,限制为 max_lowThreshold(我们之前将其设置为 100)
    2. 每次 Trackbar 注册操作时,都会调用回调函数 CannyThreshold
  6. 让我们一步一步地检查 CannyThreshold 函数:

 a、首先,我们用内核大小为 3 的过滤器对图像进行模糊处理

 blur( src_gray, detected_edges, Size(3,3) );

 b、其次,我们应用 OpenCV 函数 cv::Canny 

 Canny( detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size );
  1. 其中参数为:
    • detected_edges:源图像、灰度
    • detected_edges:检测器输出(可与输入相同)
    • lowThreshold:用户移动跟踪栏时输入的值
    • highThreshold:在程序中设置为下限的三倍(遵循 Canny 的建议)
    • kernel_size:我们将其定义为 3(内部使用的 Sobel 内核的大小)

7、我们用零填充目标图像(表示图像完全是黑色的)。

 dst = Scalar::all(0);

8、最后,我们将使用函数 cv::Mat::copyTo 仅映射图像中标识为边缘的区域(在黑色背景上)。cv::Mat::copy将 src 映像复制到 dst 上。但是,它只会复制像素具有非零值的位置。由于 Canny 检测器的输出是黑色背景上的边缘轮廓,因此生成的 dst 在除检测到的边缘之外的所有区域都将是黑色的。

 src.copyTo( dst, detected_edges);

9、我们显示我们的结果

 imshow( window_name, dst );

结果

  • 编译上面的代码后,我们可以运行它,将图像的路径作为参数。例如,使用以下图像作为输入:

OpenCV 如何实现边缘检测器,OpenCV,人工智能,C/C++,opencv,人工智能,计算机视觉

  • 移动滑块,尝试不同的阈值,我们得到以下结果:

OpenCV 如何实现边缘检测器,OpenCV,人工智能,C/C++,opencv,人工智能,计算机视觉

​请注意图像如何叠加到边缘区域的黑色背景上。


参考文献:

1、《Canny Edge Detector》---Ana Huamán文章来源地址https://www.toymoban.com/news/detail-857101.html

到了这里,关于OpenCV 如何实现边缘检测器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 序列检测器的verilog实现

    设计一个序列检测同步时序逻辑电路,要实现的功能如下: 当已有输入码流出现序列 111000或101110时输出检测信号为1 ,否则输出为0。在时序上检测到完整序列的 下一个时钟周期 输出检测结果。输入信号有效为1时表示当前输入有效,否则表示无效。之前输入依旧计入序列中

    2024年02月06日
    浏览(51)
  • 利用Verilog HDL实现序列检测器,附上仿真程序。

    序列检测器的逻辑功能就是将一个指定的比特序列从一串较长的比特流中识别出来。 例如:针对一个较长的比特流010010010011110101010…,我们希望能将比特序列为“10010”的序列检测出来,并且每次检测到10010就将输出置“1”. 注意:如序列”100100100…\\\",根据以上的介绍,会在

    2024年02月06日
    浏览(62)
  • 实验四 用集成移位寄存器实现序列检测器

    一、实验要求 用移位寄存器和与非门设计一个 1101 序列检测器。电路连续不停地工作,对 串行输入的序列进行检测,当连续检测 4 个码元符合检测码 1101 时,检测器输出 为 1 ,指示灯亮,其他情况下输出为 0 ,指示灯灭。 二、实验设备 1 . Mini-FPGA 开发板( Cyclone IV 系列

    2024年02月03日
    浏览(42)
  • 毕业设计 单片机心率检测器设计与实现 - stm32

    Hi,大家好,今天向大家介绍一个学长做的单片机项目 基于STM32的心率检测器的设计与实现 大家可用于 课程设计 或 毕业设计 主控:STM32F103C8T6 MAX30102传感器 OLED屏幕:用于显示实时心率波形 未测试时的状态:心率波形显为平稳直线,即0 将手指放上进行心率测试: 还可以把

    2024年02月07日
    浏览(41)
  • 15.1_使用Verilog设计:一个简单的状态机设计——序列检测器(可实现重复性检测)

    序列检测器的逻辑功能: 序列检测是将一个指定的序列从数字码流中识别出来。本项目要检测的序列是:10010。 设X是“数字码流的输入”,Z是“检出标记输出”;高电平是“实现指定序列”;低电平是“没有发现指定序列”。码流如下表所示。 由上述码流可知:该序列检测

    2024年01月23日
    浏览(37)
  • Verilog设计“111”检测器与“01110”检测器并测试所有情况

    使用Quartus+modelsim完成本次设计 分析 分析题目,得到其有限状态机为下图: 代码实现 Testbench 结果 Modelsim结果如下图所示,分析可知实现了题目要求。 逻辑综合出来的电路如下图所示:即只有S3状态才会输出OUT=1。 其中的state的状态机如下图所示(RLT viewer中所示),可见其与

    2024年02月08日
    浏览(56)
  • 1001序列检测器

    multisim仿真文件:1001序列检测器(mealy机)-单片机文档类资源-CSDN下载 modelsim仿真文件:1001序列检测器modelsim仿真和测试文件-单片机文档类资源-CSDN下载 实验报告:1001序列检测器实验报告-单片机文档类资源-CSDN下载 电 子 科 技 大 学 课程设计名称:           1001 序列检

    2024年02月06日
    浏览(45)
  • ChatGPT检测器(Detector)

    现阶段可使用的Detector如以下所示,在网页端有5个(3个支持中文),api有3个途径,代码运行成功的有一个。 名称 地址 特性 GPTZero https://gptzero.me/ 支持中英文,判定较为严格,有开源代码 OpenAI GPT2 Output Detector https://openai-openai-detector.hf.space/ 支持中英文,判定宽松 Hello-Simple

    2023年04月27日
    浏览(36)
  • 简易温度检测器电路原理

    在日常生活中,对温度的及时检测能够减免火灾的发生,所以今天就说说温度检测器。 实际功能 在常温下显示数字0,随着温度的升高,数码管逐步显示1、3、8,分别代表三档温度,并且在显示8的时候,LED灯开始闪烁,代表温度过高而报警,当温度下降时,数码管的显示状态

    2024年02月09日
    浏览(39)
  • 实验 5 巴克码检测器

    5.1 实 验 目 的 (1) 了解通信领域中经常使用的巴克码检测器的设计方法。 (2) 掌握使用状态机设计时序电路的方法。 5.2 实 验 仪 器 与 器 材 (1) EDA 开发软件 一 套 (2) 微 机 一 台 (3) 实验开发系统 一 台 (4) 打印机 一 台 (5) 其他器件与材料 若 干 5.3 实 验 说 明 巴 克 码 检 测

    2024年02月01日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包