Opencv图像处理---Canny边缘检测

理论

Canny算法旨在满足三个主要标准:

  • 低错误率:意味着只检测存在的边缘。
  • 良好的定位:必须最小化检测到的边缘像素和真实边缘像素之间的距离。
  • 最小响应:每个边缘只有一个检测器响应。

步骤

  • 过滤掉任何噪音。 高斯滤波器用于此目的。 可能使用的大小为5的高斯内核的示例如下所示:
  • 找到图像的强度梯度。 为此,我们遵循类似Sobel的程序:
  1. 应用一对卷积掩模(在x和y方向):
  2. 找到梯度强度和方向:
  • 应用非最大抑制。 这将删除不被视为边缘一部分的像素。 因此,仅保留细线(候选边缘)。
  • 迟滞:最后一步。 Canny确实使用了两个阈值(上限和下限):
  1. 如果像素梯度高于上阈值,则该像素被接受为边缘
  2. 如果像素梯度值低于下阈值,则拒绝它
  3. 如果像素梯度在两个阈值之间,则仅当它连接到高于上阈值的像素时才接受它。

代码


#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
Mat src, src_gray;
Mat dst, detected_edges;
int edgeThresh = 1;
int lowThreshold;
int const max_lowThreshold = 100;
int ratio = 3;
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, char** argv )
{
  src = imread( argv[1] );
  if( src.empty() )
    { 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;
}

解释

  • 创建一些所需的变量:
  1. 我们建立一个较低的比率:上限阈值为3:1(可变比例)
  2. 我们将内核大小设置为3(用于由Canny函数在内部执行的Sobel操作)
  3. 我们为下限阈值设置了最大值100。
  • 加载源图像:
  • 创建一个src相同类型和大小的矩阵(将是dst)
  • 将图像转换为灰度(使用函数cv :: cvtColor:)
  • 创建一个窗口以显示结果
  • 创建一个滑块栏,供用户输入Canny探测器的下限:
  1. 滑动条控制的变量是低阈值,具有最大低阈值限制(我们之前设置为100)
  2. 每次滑动条注册一个动作时,都会调用回调函数CannyThreshold。
  • 让我们一步一步检查CannyThreshold函数:
  1. 首先,我们使用内核大小为3的过滤器模糊图像:
  2. 其次,我们应用OpenCV函数cv :: Canny:
  • 我们用零填充dst图像(意味着图像是完全黑色的)。
  • 最后,我们将使用函数cv :: Mat :: copyTo仅映射图像中标识为边的区域(在黑色背景上)。
  • 我们显示结果:

效果

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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值