一、边缘检测概念

图像的边缘检测的原理是检测出图像中所有灰度值变化较大的点,而且这些点连接起来就构成了若干线条,这些线条就可以称为图像的边缘。效果如图:

接下来介绍一下边缘提取的几种算子,具体证明过程可能会比较简单,重点在函数的使用上。

二、算法实现:

1.索贝尔算子

索贝尔算子(Sobel operator)计算。

C++: void Sobel(InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize=3, double scale=1, double delta=0, intborderType=BORDER_DEFAULT )
参数说明:
  • src – 输入图像。
  • dst – 输出图像,与输入图像同样大小,拥有同样个数的通道。
  • ddepth –
    输出图片深度;下面是输入图像支持深度和输出图像支持深度的关系:
    • src.depth() = CV_8Uddepth = -1/CV_16S/CV_32F/CV_64F
    • src.depth() = CV_16U/CV_16Sddepth = -1/CV_32F/CV_64F
    • src.depth() = CV_32Fddepth = -1/CV_32F/CV_64F
    • src.depth() = CV_64Fddepth = -1/CV_64F

    当 ddepth为-1时, 输出图像将和输入图像有相同的深度。输入8位图像则会截取顶端的导数。

  • xorder – x方向导数运算参数。
  • yorder – y方向导数运算参数。
  • ksize – Sobel内核的大小,可以是:1,3,5,7。
  • scale – 可选的缩放导数的比例常数。
  • delta – 可选的增量常数被叠加到导数中。
  • borderType – 用于判断图像边界的模式。

代码注释:

  在边沿检测中,常用的一种模板是Sobel 算子。Sobel 算子有两个,一个是检测水平边沿的;另一个是检测垂直平边沿的 。 由于Sobel算子是滤波算子的形式,用于提取边缘,可以利用快速卷积函数,简单有效,因此应用广泛。美中不足的是,Sobel算子并没有将图像的主体与背景严格地区分开来,换言之就是Sobel算子没有基于图像灰度进行处理,由于Sobel算子没有严格地模拟人的视觉生理特征,所以提取的图像轮廓有时并不能令人满意。在观测一幅图像的时候,我们往往首先注意的是图像与背景不同的部分,正是这个部分将主体突出显示,基于该理论,我们可以给出阈值化轮廓提取算法,该算法已在数学上证明当像素点满足正态分布时所求解是最优的。

//在x方向求图像近似导数
Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT ); //在y方向求图像近似导数
Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );

2.Canny算子

函数原型:

void cvCanny(const CvArr* image, CvArr* edges,double threshold1,double threshold2,int aperture_size=3);

函数说明:

第一个参数表示输入图像,必须为单通道灰度图。

第二个参数表示输出的边缘图像,为单通道黑白图。

第三个参数和第四个参数表示阈值,这二个阈值中当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割即如果一个像素的梯度大与上限值,则被认为是边缘像素,如果小于下限阈值,则被抛弃。如果该点的梯度在两者之间则当这个点与高于上限值的像素点连接时我们才保留,否则删除。

第五个参数表示Sobel 算子大小,默认为3即表示一个3*3的矩阵。详细的数学原理可以查阅专业书籍。

代码注释:

  Canny算子实现起来较为麻烦,Canny算子是一个具有滤波,增强,检测的多阶段的优化算子,在进行处理前,Canny算子先利用高斯平滑滤波器来平滑图像以除去噪声,Canny分割算法采用一阶偏导的有限差分来计算梯度幅值和方向,在处理过程中,Canny算子还将经过一个非极大值抑制的过程,最后Canny算子还采用两个阈值来连接边缘。

  再强调一下Canny算子的两个参数:第一个是低阈值,第二个高阈值。高阈值比较严格,求的边缘很少,认为高阈值的边缘都是有效。低阈值宽松,求的边缘很多(一般包括了高阈值求到的边缘),其中不少是无效的边缘(反正不想要的)。先用高阈值求边缘。canny求得的边缘希望是连在一起的(通常是封闭的),但高阈值求的边缘一般断断续续。断开的地方如果低阈值求的边缘存在,就用低阈值的边缘接上去,目的让边缘尽量都连在一起。其它情况下低阈值的边缘是不用的。两个阈值是有区别的,高的那个阈值是将要提取轮廓的物体与背景区分开来,就像阈值分割的那个参数一样,是决定目标与背景对比度的,低的那个阈值是用来平滑边缘的轮廓,有时高的阈值设置太大了,可能边缘轮廓不连续或者不够平滑,通过低阈值来平滑轮廓线,或者使不连续的部分连接起来

Canny(src_gray, grad_y, 30,80);

三、代码实现

#include <opencv.hpp>
using namespace cv;
int main()
{
Mat srcImage;
srcImage = imread("d://1.png");
imshow("【原图】", srcImage);
Mat dst=srcImage; // 构造目标类
//Sobel(srcImage, dst, 0, 1, 0);
Canny(srcImage, dst,30,80);
imshow("【处理后】", dst);
waitKey();
return 0;
}

效果图:

Canny算子处理:

Sobel处理:

Opencv学习笔记3:边缘检测算子的实现方法的更多相关文章

  1. Opencv学习笔记2:图像模糊作用和方法

    一.意义和作用: 图像的模糊处理就是将图片处理的更加模糊,如下图,左侧是原图,右侧是经过处理之后的图片. 从主观意愿上说,我们希望看到清晰的图像,而不是模糊的图像.所以很多时候我们听说还有一种专门进行 ...

  2. OpenCV 学习笔记 07 目标检测与识别

    目标检测与识别是计算机视觉中最常见的挑战之一.属于高级主题. 本章节将扩展目标检测的概念,首先探讨人脸识别技术,然后将该技术应用到显示生活中的各种目标检测. 1 目标检测与识别技术 为了与OpenCV ...

  3. OpenCV 学习笔记 02 使用opencv处理图像

    1 不同色彩空间的转换 opencv 中有数百种关于不同色彩空间的转换方法,但常用的有三种色彩空间:灰度.BRG.HSV(Hue-Saturation-Value) 灰度 - 灰度色彩空间是通过去除彩 ...

  4. OpenCV学习笔记5

    OpenCV学习笔记5 图像变换 傅里叶变换 这里可以先学习一下卷积分,了解清除卷积的过程和实际意义,在看这一章节的内容. 原理: 傅里叶变换经常被用来分析不同滤波器的频率特性.我们可以使用 2D 离 ...

  5. OpenCV学习笔记3

    OpenCV学习笔记3 图像平滑(低通滤波) 使用低通滤波器可以达到图像模糊的目的.这对与去除噪音很有帮助.其实就是去除图像中的高频成分(比如:噪音,边界).所以边界也会被模糊一点.(当然,也有一些模 ...

  6. opencv学习笔记(七)SVM+HOG

    opencv学习笔记(七)SVM+HOG 一.简介 方向梯度直方图(Histogram of Oriented Gradient,HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子 ...

  7. opencv学习笔记(六)直方图比较图片相似度

    opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...

  8. opencv学习笔记(五)镜像对称

    opencv学习笔记(五)镜像对称 设图像的宽度为width,长度为height.(x,y)为变换后的坐标,(x0,y0)为原图像的坐标. 水平镜像变换: 代码实现: #include <ios ...

  9. opencv学习笔记(四)投影

    opencv学习笔记(四)投影 任选了一张图片用于测试,图片如下所示: #include <cv.h> #include <highgui.h> using namespace ...

  10. opencv学习笔记(三)基本数据类型

    opencv学习笔记(三)基本数据类型 类:DataType 将C++数据类型转换为对应的opencv数据类型 OpenCV原始数据类型的特征模版.OpenCV的原始数据类型包括unsigned ch ...

随机推荐

  1. CSS浏览器兼容问题集-第二部分

    11.高度不适应 高度不适应是当内层对象的高度发生变化时外层高度不能自动进行调节,特别是当内层对象使用margin 或paddign 时.   例:  #box {background-color:# ...

  2. 【BZOJ】2125: 最短路 圆方树(静态仙人掌)

    [题意]给定带边权仙人掌图,Q次询问两点间最短距离.n,m,Q<=10000 [算法]圆方树处理仙人掌问题 [题解]树上的两点间最短路问题,常用倍增求LCA解决,考虑扩展到仙人掌图. 先对仙人掌 ...

  3. oozie与mapreduce简单案例

    准备工作  拷贝原来的模板 mkdir oozie-apps cd oozie-apps/ cp -r ../examples/apps/mar-reduce . mv map-reduce mr-w ...

  4. Problem D. Berland Railroads Gym - 101967D (思维)

    题目链接:https://cn.vjudge.net/contest/274029#problem/D 题目大意:给你0-9每个数的个数,然后让你找出最大的数,满足的条件是任意三位相连的都能被三整除. ...

  5. 【IDEA】IDEA设置新建文件的模板

    今天在IDEA中新建JS文件的时候想着也像WebStorm一样可以显示作者和时间,所以就研究了下在IDEA中修改文件创建时的模板. 点击settings找到File and Code Template ...

  6. 如何通过掩码计算可用的IP数量

    假设掩码是28,28也就是28个1.本身掩码是255.255.255.255那么转换成二进制也就是 11111111,11111111,11111111,11111111 那么28个1也就是: 111 ...

  7. stegsolve使用探究

    应该也不是工具的问题吧,更多的是图片.但是不知道咋取就写工具了. 比如:http://ctf5.shiyanbar.com/stega/chromatophoria/steg.png 我在想为毛要选择 ...

  8. docker之安装和基本使用(一)

    前言 开始折腾docker. 主要概念 容器:独立运行的一个或一组应用,与其他应用完全独立. 镜像:用于创建 Docker容器的模板. 仓库:用于收纳镜像文件,可以理解为代码控制中的代码仓库 注意: ...

  9. python3-可变和不可变数据类型

    可变:[ ]    { } 不可变:int    str   ( )     应用实例: 把列表l,追加到列表s中,现在网列表l中追加一个5,打印列表s可以看到,列表s中的列表l中也有5. d={&q ...

  10. C++学习之路(九):从菱形继承引入的对象模型

    一.单继承 class A {int a;}; class B : public A {int b;}; 普通的单继承关系,类的大小是由其虚表指针和非静态成员函数大小决定.故上述sizeof(A)的大 ...