边缘检测:

一、canny算子

Canny边缘检测根据对信噪比与定位乘积进行测度,得到最优化逼近算子,也就是Canny算子。类似与 LoG 边缘检测方法,也属于先平滑后求导数的方法。

二、canny算法描述

1.首先进行高斯平滑滤波;

2、然后计算像素点的梯度(利用sobel算子)

3、计算幅值和夹角

4、非极大值抑制(NMS)幅值和夹角,如下图所示,就是比较梯度方向前后像素梯度的大小。

上图中左右图:g1、g2、g3、g4都代表像素点,很明显它们是c的八领域中的4个,左图中c点是我们需要判断的点,蓝色的直线是它的梯度方向,也就是说c如果是局部极大值,它的梯度幅值M需要大于直线与g1g2和g2g3的交点,dtmp1和dtmp2处的梯度幅值。但是dtmp1和dtmp2不是整像素,而是亚像素,也就是坐标是浮点的,那怎么求它们的梯度幅值呢?线性插值,例如dtmp1在g1、g2之间,g1、g2的幅值都知道,我们只要知道dtmp1在g1、g2之间的比例,就能得到它的梯度幅值,而比例是可以靠夹角计算出来的,夹角又是梯度的方向。

写个线性插值的公式:设g1的幅值M(g1),g2的幅值M(g2),则dtmp1可以很得到:

M(dtmp1)=w*M(g2)+(1-w)*M(g1)

其中w=distance(dtmp1,g2)/distance(g1,g2)

distance(g1,g2) 表示两点之间的距离。实际上w是一个比例系数,这个比例系数可以通过梯度方向(幅角的正切和余切)得到。

5、双阈值选取

  • 将低于阈值的所有值赋零,得到图像的边缘阵列

  • 阈值τ取得太低->假边缘
  • 阈值τ取得太高->部分轮廊丢失

Canny算法中减少假边缘数量的方法是采用双阈值法。选择两个阈值,根据高阈值得到一个边缘图像,这样一个图像含有很少的假边缘,但是由于阈值较高,产生的图像边缘可能不闭合,为解决这样一个问题采用了另外一个低阈值。
        在高阈值图像中把边缘链接成轮廓,当到达轮廓的端点时,该算法会在断点的8邻域点中寻找满足低阈值的点,再根据此点收集新的边缘,直到整个图像边缘闭合。

 三、Canny方法

void Canny(InputArray image,

                OutputArray edges,

                double threshold1,

                double threshold2,

                int apertureSize=,

                bool L2gradient=false)
参数详解:
  • 第一个参数,InputArray类型的image,输入图像,填Mat类对象即可,且需为单通道8位图像
  • 第二个参数,OutputArray类型的edges,输出边缘图,和源图像有一样的尺寸和类型
  • 第三个参数,double类型的threshold1,第一个滞后性阈值
  • 第四个参数,double类型的threshold2,第二个滞后性阈值
  • 第五个参数,int类型的apertureSize,表示应用Sobel算子的孔径大小,默认值3
  • 第六个参数,bool类型的L2gradient,一个计算图像梯度幅值的标识,默认值false

注意:两个阈值中较小的值用于边缘连接,较大的值用来控制强边缘的初始段,推荐高低阈值比为2:1到3:1之间

 四、opencv中的实现

1、图像灰度化;

2、高斯滤波(blur)

3、计算梯度

4、用双阈值方法检测和连接边缘

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <math.h>
using namespace cv;
int main(int argc, char *argv[])
{
    Mat img = imread("lena.jpg", CV_LOAD_IMAGE_COLOR);
    if(img.empty())
       return -1;
    Mat src_gray,src_blur,dst;
    cvtColor(img,src_gray,CV_BGR2GRAY);
    blur(src_gray,src_blur,Size(3,3));
    Canny(src_blur,dst,30,200);
    namedWindow( "lena", CV_WINDOW_AUTOSIZE );
    imshow("lena", img);
    imshow("canny",dst);
    waitKey(0);
    return 0;
}
 

【opencv实践】边缘检测的更多相关文章

  1. OpenCV: Canny边缘检测算法原理及其VC实现详解(转载)

    原文地址:http://blog.csdn.net/likezhaobin/article/details/6892176 原文地址:http://blog.csdn.net/likezhaobin/ ...

  2. OpenCV 之 边缘检测

    上一篇 <OpenCV 之 图像平滑> 中,提到的图像平滑,从信号处理的角度来看,实际上是一种“低通滤波器”. 本篇中,数字图像的边缘,因为通常都是像素值变化剧烈的区域 (“高频”),故可 ...

  3. 【OpenCV】边缘检测:Sobel、拉普拉斯算子

    推荐博文,博客.写得很好,给个赞. Reference Link : http://blog.csdn.net/xiaowei_cqu/article/details/7829481 一阶导数法:梯度 ...

  4. opencv实践::切边

    问题描述 真实案例,扫描仪扫描到的法律文件,需要切边,去掉边 缘空白,这样看上去才真实. #include <opencv2/opencv.hpp> #include <iostre ...

  5. SVM:从理论到OpenCV实践

    (转载请注明出处:http://blog.csdn.net/zhazhiqiang/ 未经允许请勿用于商业用途)   一.理论 参考网友的博客: (1)[理论]支持向量机1: Maximum Marg ...

  6. HOG:从理论到OpenCV实践

    (转载请注明出处:http://blog.csdn.net/zhazhiqiang/ 未经允许请勿用于商业用途) 一.理论 1.HOG特征描述子的定义:     locally normalised ...

  7. OpenCV实践之路——人脸检测(C++/Python) 【转】

    转自:http://blog.csdn.net/xingchenbingbuyu/article/details/51105159 版权声明:本文为博主原创文章,转载请联系作者取得授权. 本文由@星沉 ...

  8. OpenCV实践之路——Python的安装和使用

    本文由@星沉阁冰不语出品,转载请注明作者和出处. 文章链接:http://blog.csdn.net/xingchenbingbuyu/article/details/50936076 微博:http ...

  9. opencv实践::对象提取与测量

    问题描述 照片是来自太空望远镜的星云图像,科学家想知道它的面 积与周长. 解决思路 方法一: 通过二值分割+图像形态学+轮廓提取 #include <opencv2/opencv.hpp> ...

随机推荐

  1. DVWA-XSS学习笔记

    DVWA-XSS XSS概念:由于web应用程序对用户的输入过滤不严,通过html注入篡改网页,插入恶意脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击. XSS类型: 反射型XSS:只是简单地把 ...

  2. 利用ELK分析Nginx日志生产实战(高清多图)

    本文以api.mingongge.com.cn域名为测试对象进行统计,日志为crm.mingongge.com.cn和risk.mingongge.com.cn请求之和(此二者域名不具生产换环境统计意 ...

  3. Python 原生协程------asyncio

    协程 在python3.5以前,写成的实现都是通过生成器的yield from原理实现的, 这样实现的缺点是代码看起来会很乱,于是3.5版本之后python实现了原生的协程,并且引入了async和aw ...

  4. 在C++中定义常量

    在 C++ 中,有两种简单的定义常量的方式: 使用 #define 预处理器. 使用 const 关键字 使用 #define 预处理器: #define identifier value: #inc ...

  5. 基于 docker 的redis 主从+哨兵(快速部署)

    很简单(字多的步骤见:http://www.cnblogs.com/vipzhou/p/8580495.html) 1.直接启动3个容器 docker network create --subnet ...

  6. Activiti6-FormService(学习笔记)重要

    设置流程定义文件: <?xml version="1.0" encoding="UTF-8"?> <definitions xmlns=&qu ...

  7. 泛型与object

    一.泛型通俗的理解就是限制list集合里面的数据类型 比如List<int>,就限制LIST里面必须是int,这样放入其他就有报错(保证了安全),然后从 list里取元素,就不需要强制转化 ...

  8. git在多迭代版本的应用

    名词解释: 1.迭代: 就是对于项目功能的一个分类.如项目需要新增一个地图功能,则地图功能是一个迭代. 2.gitlab机器人 操作: 1.如果将要进行一个新功能的开发,从稳定分支上拉取创建一个新的分 ...

  9. sql 根据身份证号码计算年龄

    ,), GETDATE()) / 365.25) from ConstructionInfo

  10. P1462 通往奥格瑞玛的道路 (二分+最短路)

    题目 P1462 通往奥格瑞玛的道路 给定\(n\)个点\(m\)条边,每个点上都有点权\(f[i]\),每条边上有边权,找一条道路,使边权和小于给定的数\(b\),并使最大点权最小. 解析 二分一下 ...