一:Canny算法介绍

Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:
好的检测- 算法能够尽可能多地标识出图像中的实际边缘。
好的定位- 标识出的边缘要尽可能与实际图像中的实际边缘尽可能接近。
最小响应- 图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。

推文:Canny边缘检测算法原理及其VC实现详解(一)

1.高斯模糊--GaussianBlur  消除噪声。 一般情况下,使用高斯平滑滤波器卷积降噪。,因为canny是对噪声敏感的算法,所以先降噪,但是降噪不要太过,以免丢失
2.灰度转换--cvtColor  
3.计算梯度--Sobel/Scharr
4.非最大信号抑制
5.高低阈值输出二值图像

补充:

非最大信号抑制

在Canny算法中,非极大值抑制是进行边缘检测的重要步骤,通俗意义上是指寻找像素点局部最大值,将非极大值点所对应的灰度值置为0
sobel算子中有一个x,y
根据x,y可以求出一个θ角度
1.要进行非极大值抑制,就首先要确定像素点C的灰度值在其8值邻域内是否为最大。是最大则下一步
2.图中蓝色的线条方向为C点的梯度方向,这样就可以确定其局部的最大值肯定分布在这条线上,也即出了C点外,梯度方向的交点dTmp1和dTmp2这两个点的值也可能会是局部最大值。
因此,判断C点灰度与这两个点灰度大小即可判断C点是否为其邻域内的局部最大灰度点。
.如果经过判断,C点灰度值小于这两个点中的任一个,那就说明C点不是局部极大值,那么则可以排除C点为边缘。
完成非极大值抑制后,会得到一个二值图像,非边缘的点灰度值均为0,可能为边缘的局部灰度极大值点可设置其灰度为128。
根据下文的具体测试图像可以看出,这样一个检测结果还是包含了很多由噪声及其他原因造成的假边缘。因此还需要进一步的处理。

高低阈值输出二值图像

二:Canny边缘提取实现

def edge_demo(image):
#1.高斯模糊
blurred = cv.GaussianBlur(image,(3,3),0)
#2.灰度转换
gray = cv.cvtColor(blurred,cv.COLOR_RGB2GRAY)
#3.计算梯度
xgrad = cv.Sobel(gray,cv.CV_16SC1,1,0) #canny方法API要求不允许使用浮点数
ygrad = cv.Sobel(gray,cv.CV_16SC1,0,1)
#4.Canny方法中包含非最大信号抑制和双阈值输出
edge_output = cv.Canny(xgrad,ygrad,50,150) #50是低阈值,150是高阈值
cv.imshow("Canny Edge"
,edge_output) dst = cv.bitwise_and(image,image,mask=edge_output)  #相与,获取颜色
cv.imshow("Color Edge",dst)
src = cv.imread("./g.png")  #读取图片
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE) #创建GUI窗口,形式为自适应
cv.imshow("input image",src) #通过名字将图像和窗口联系 edge_demo(src) cv.waitKey(0) #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作
cv.destroyAllWindows() #销毁所有窗口

使用Canny计算梯度

def edge_demo(image):
#1.高斯模糊
blurred = cv.GaussianBlur(image,(3,3),0)
#2.灰度转换
gray = cv.cvtColor(blurred,cv.COLOR_RGB2GRAY)
#3.直接传入灰度图像,Canny方法中包含计算梯度,非最大信号抑制和双阈值输出
edge_output = cv.Canny(gray,50,150
) #50是低阈值,150是高阈值
cv.imshow("Canny Edge",edge_output) dst = cv.bitwise_and(image,image,mask=edge_output)
cv.imshow("Color Edge",dst)

相关知识补充

(一)Canny方法

(1)需要我们求出梯度

Canny(dx, dy, threshold1, threshold2[, edges[, L2gradient]]) -> edges
使用带自定义图像渐变的Canny算法在图像中查找边缘,

其函数原型为:Canny(dx, dy, threshold1, threshold2[, edges[, L2gradient]]) -> edges

dx参数表示输入图像的x导数(x导数满足16位,选择CV_16SC1或CV_16SC3)

dy参数表示输入图像的y导数(y导数满足16位,选择CV_16SC1或CV_16SC3)。

threshold1参数表示设置的低阈值。

threshold2参数表示设置的高阈值,一般设定为低阈值的3倍 (根据Canny算法的推荐)。

edges参数表示输出边缘图像,单通道8位图像。

L2gradient参数表示L2gradient参数表示一个布尔值,如果为真,则使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开方),否则使用L1范数(直接将两个方向导数的绝对值相加)。

(2)直接调用Canny算法在单通道灰度图像中查找边缘,

def Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None): # real signature unknown; restored from __doc__
image参数表示8位输入图像。

threshold1参数表示设置的低阈值。

threshold2参数表示设置的高阈值,一般设定为低阈值的3倍 (根据Canny算法的推荐)。

edges参数表示输出边缘图像,单通道8位图像。

apertureSize参数表示Sobel算子的大小。

L2gradient参数表示一个布尔值,如果为真,则使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开方),否则使用L1范数(直接将两个方向导数的绝对值相加)。

OpenCV---Canny边缘提取的更多相关文章

  1. OpenCV使用边缘提取、腐蚀、轮廓进行车牌定位

    http://blog.csdn.net/superdont/article/details/24935383 OpenCV使用边缘提取.腐蚀.轮廓进行车牌定位 2014-05-03 21:38 67 ...

  2. opencv python:Canny边缘提取

    Canny是边缘提取算法,在1986年提出的 是一个很好的边缘检测器 Canny算法介绍 非最大信号抑制: 高低阈值连接: example import cv2 as cv import numpy ...

  3. 13、OpenCV Python canny边缘提取

    __author__ = "WSX" import cv2 as cv import numpy as np def lapalian_demo(image): #拉普拉斯算子 # ...

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

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

  5. Opencv Canny

    #include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...

  6. opencv:边缘提取

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  7. opencv::Canny边缘检测

    Canny算法介绍 五步 in cv::Canny 高斯模糊 - GaussianBlur 灰度转换 - cvtColor 计算梯度 – Sobel/Scharr 非最大信号抑制 高低阈值输出二值图像 ...

  8. OpenCV Canny 边缘检测

    #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #i ...

  9. python opencv Sobel、Laplace、canny算子的边缘提取 以及参数解析

    前提:各种算子不完全区分好坏,但根据我实际操作分析得到,有的算子之间效果大相径庭,但有的也很相似,也就是各有各的用法,这里按 Sobel.Laplace.canny三种算子作比较,看其结果: 一.  ...

  10. Python+OpenCV图像处理(十三)—— Canny边缘检测

    简介: 1.Canny边缘检测算子是John F. Canny于 1986 年开发出来的一个多级边缘检测算法. 2.Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是: 好的检测- ...

随机推荐

  1. [shell] sed学习

    Q:匹配内容有1没有a的行 echo -e "1a\n2b\n1b\n2a" | sed -n '/1/{/a/d;p}' echo -e "1a\n2b\n1b\n2a ...

  2. hadoop HA sshfen切换隔离时无法跳转ssh: bash: fuser: 未找到命令

    在zkfc的日志里面,有一个warn:PATH=$PATH:/sbin:/usr/sbin fuser -v -k -n tcp 8090 via ssh: bash: fuser: 未找到命令原因是 ...

  3. nginx gzip压缩配置

    gzip(GNU-ZIP)是一种压缩技术.经过gzip压缩后页面大小可以变为原来的30%甚至更小,这样,用户浏览页面的时候速度会块得多.gzip 的压缩页面需要浏览器和服务器双方都支持,实际上就是服务 ...

  4. 王者荣耀交流协会 - 第6次Scrum会议

    Scrum master :刘耀泽 补充:由于上次的scrum会议博客没有按时交上去,因此在这里给出上次scrum会议的链接: http://www.cnblogs.com/rensijia/p/76 ...

  5. 遇到Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so问题的解决方法

    运行一个基于tensorflow的模型时,遇到Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so问题. 解决方法:打开 ...

  6. asp.netcore mvc 权限拦截

    1-背景介绍 需要做一个简单权限系统,基于 角色,用户,菜单 的模式 基于IActionFilter全局拦截,在内部跳转或者浏览器跳转的时候,拦截是成功的,当通过AJAX 请求的时候,页面就不会跳转 ...

  7. [转]Android试验:如果View的ID相同会出现什么效果?

    1.实验:通过布局编辑器强行指定两个button id相同,然后在代码中通过findViewById()获得句柄后修改其文本.  实验结果:只有一个button的文本变化了,另一个不受影响.  2.实 ...

  8. lintcode-421-简化路径

    421-简化路径 给定一个文档(Unix-style)的完全路径,请进行路径简化. 样例 "/home/", => "/home" "/a/./ ...

  9. Kafka集群无法外网访问问题解决攻略

    Kafka无法集群外网访问问题解决方法  讲解本地消费者和生产者无法使用远程Kafka服务器的处理办法 服务搭建好Kafka服务后,机本.测试 OK,外面机器却无法访问,很是怪异. 环境说明:  Ka ...

  10. Windows下多线程编程(一)

    前言 熟练掌握Windows下的多线程编程,能够让我们编写出更规范多线程代码,避免不要的异常.Windows下的多线程编程非常复杂,但是了解一些常用的特性,已经能够满足我们普通多线程对性能及其他要求. ...