OpenCV---Canny边缘提取
一:Canny算法介绍
Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:
好的检测- 算法能够尽可能多地标识出图像中的实际边缘。
好的定位- 标识出的边缘要尽可能与实际图像中的实际边缘尽可能接近。
最小响应- 图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。
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边缘提取的更多相关文章
- OpenCV使用边缘提取、腐蚀、轮廓进行车牌定位
http://blog.csdn.net/superdont/article/details/24935383 OpenCV使用边缘提取.腐蚀.轮廓进行车牌定位 2014-05-03 21:38 67 ...
- opencv python:Canny边缘提取
Canny是边缘提取算法,在1986年提出的 是一个很好的边缘检测器 Canny算法介绍 非最大信号抑制: 高低阈值连接: example import cv2 as cv import numpy ...
- 13、OpenCV Python canny边缘提取
__author__ = "WSX" import cv2 as cv import numpy as np def lapalian_demo(image): #拉普拉斯算子 # ...
- OpenCV: Canny边缘检测算法原理及其VC实现详解(转载)
原文地址:http://blog.csdn.net/likezhaobin/article/details/6892176 原文地址:http://blog.csdn.net/likezhaobin/ ...
- Opencv Canny
#include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...
- opencv:边缘提取
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...
- opencv::Canny边缘检测
Canny算法介绍 五步 in cv::Canny 高斯模糊 - GaussianBlur 灰度转换 - cvtColor 计算梯度 – Sobel/Scharr 非最大信号抑制 高低阈值输出二值图像 ...
- OpenCV Canny 边缘检测
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #i ...
- python opencv Sobel、Laplace、canny算子的边缘提取 以及参数解析
前提:各种算子不完全区分好坏,但根据我实际操作分析得到,有的算子之间效果大相径庭,但有的也很相似,也就是各有各的用法,这里按 Sobel.Laplace.canny三种算子作比较,看其结果: 一. ...
- Python+OpenCV图像处理(十三)—— Canny边缘检测
简介: 1.Canny边缘检测算子是John F. Canny于 1986 年开发出来的一个多级边缘检测算法. 2.Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是: 好的检测- ...
随机推荐
- ntp时钟服务器配置
集群中时间不同步有可能会让大数据的应用程序运行混乱,造成不可预知的问题,比如Hbase,当时间差别过大时就会挂掉,所以在大数据集群中,ntp服务,应该作为一种基础的服务,以下在演示在CentOS 7. ...
- ES6的新特性(8)——数组的扩展
数组的扩展 扩展运算符 含义 扩展运算符(spread)是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. console.log(...[1, 2, 3]) / ...
- AppCan 之初体验
平台概述 什么是AppCan 移步这里,楼主的一句话:可以匹敌 Phonegap .Titanium .Sencha Touch .MUI .ImagApp.Nitrous .apicloud .起步 ...
- 关于XML文档操作类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.X ...
- FivePlus——分工理解
最终的游戏方案 游戏采用回合制,每回合双方英雄各自轮流选择移动和攻击以及大招,选择结束进行结算 英雄/小兵/塔的攻击力/大招效果参照作业要求,如果发现不均衡再进行调整 UI界面考虑使用QT或者命令行界 ...
- 周总结<1>
由于都不清楚周总结的格式,所以就没有写了.不过,上次听了老师的课,觉得应该要好好写写了,至少今后可以明白自己有做过什么事情,至少不会觉得自己在各个方面没有收获.不过,可能没有按照格式来写.希望老师体谅 ...
- JAVA第三次笔记
- PHP SQL查询结果在页面上是乱码
今天系统网页出现这样一个问题:下图左边类型栏数据是没显示出来 打印SQL查询的数据是有的 原因是:————> eval函数里'return '这一字符串一定要有空格哈,没有空格,这语句就是错的. ...
- 【转】MySQL数据表中记录不存在则插入,存在则更新
mysql 记录不存在时插入在 MySQL 中,插入(insert)一条记录很简单,但是一些特殊应用,在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,本文介绍的就是这个问 ...
- web移动开发最佳实践之js篇
一.js概述 js即JavaScript,是被设计用来验证表单.检测浏览器.创建cookies.改进设计以及更多应用的网络脚本语言,它非常容易使用.在web应用中,它是主要的编程语言,主要用途是进行各 ...