一、原理简介

边缘检测原理 - Sobel, Laplace, Canny算子

X方向Sobel算子

-1 -2 -1
0 0 0
1 2 1

Y方向Sobel算子

-1 0 1
-2 0 2
-1 0 1

Laplace算子

1 1 1
1 -8 1
1 1 1

Canny 边缘检测算子

高斯滤波器平滑图像

一阶差分偏导计算梯度值和方向

对梯度值不是极大值的地方进行抑制

用双阈值连接图上的联通点

通俗说一下,
1.用高斯滤波主要是去掉图像上的噪声。
2.计算一阶差分,OpenCV 源码中也是用 sobel 算子来算的。
3.算出来的梯度值,把不是极值的点,全部置0,去掉了大部分弱的边缘。所以图像边缘会变细。
4.双阈值 t1, t2, 是这样的,t1 <= t2
大于 t2 的点肯定是边缘
小于 t1 的点肯定不是边缘
在 t1, t2 之间的点,通过已确定的边缘点,发起8领域方向的搜索(广搜),图中可达的是边缘,不可达的点不是边缘。
最后得出 canny 边缘图。

二、代码演示

有关函数 convertScaleAbs,文档解释如下,不过这里不使用其放缩功能

1、Sobel 边缘检测算子

由于需要指定横向纵向,所以分两步进行,最后组合即可,

	cv::Mat image = cv::imread("test.jpg");
cv::imshow("原图", image);
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY); cv::Mat contours;
cv::Mat sobelX, sobelY;
cv::Sobel(
image,
sobelX,
CV_16S, // 图像depth,输入8U,输出16S防止外溢
1, 0, // xorder, yorder
3, // 内核尺寸
1, 1 // 输出结果乘alpha加beta
);
cv::convertScaleAbs(sobelX, sobelX);
cv::imshow("Sobel_X", sobelX);
cv::Sobel(
image,
sobelY,
CV_8U,
0, 1,
3,
1, 1
);
cv::convertScaleAbs(sobelY, sobelY);
cv::imshow("Sobel_Y", sobelY);
cv::addWeighted(sobelX, 0.5, sobelY, 0.5, 0, contours);
cv::imshow("Sobel", contours);

XY单方向输出如下,

两这合并如下,

2、Laplace 边缘检测算子

	// cv::Mat image = cv::imread("skin.jfif");
cv::Mat image = cv::imread("test.jpg");
cv::imshow("原图", image);
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY); cv::Mat contours;
cv::GaussianBlur(gray, gray, cv::Size(5, 5), 1.5);
cv::Laplacian(
gray,
contours,
CV_16S,
3, // 内核尺寸
1, 0 // 放缩因子
); cv::convertScaleAbs(contours, contours);
cv::imshow("Laplacian", contours);

3、Canny 边缘检测算子

	// cv::Mat image = cv::imread("skin.jfif");
cv::Mat image = cv::imread("test.jpg");
cv::imshow("原图", image);
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY); cv::Mat contours;
cv::GaussianBlur(gray, gray, cv::Size(5, 5), 1.5);
cv::Canny(
gray,
contours,
10, // 低阈值
150 // 高阈值
);
cv::imshow("Canny", contours);

高低阈值参数的设定对于检测效果影响很大,一般来说低阈值检测出十分琐碎的边缘,且设置的越低检测出来的越多,而高阈值这决定了保留多少边缘,对于上图,我们将高阈值下调至50查看一下效果,会发现保留细节数目增加了

附录、函数总览

void edge() {
// cv::Mat image = cv::imread("skin.jfif");
cv::Mat image = cv::imread("test.jpg");
cv::imshow("原图", image);
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY); cv::Mat contours;
cv::GaussianBlur(gray, gray, cv::Size(5, 5), 1.5);
cv::Canny(
gray,
contours,
10, // 低阈值
150 // 高阈值
);
cv::imshow("Canny", contours); cv::Laplacian(
gray,
contours,
CV_16S,
3, // 内核尺寸
1
);
cv::Mat abs_dst;
cv::convertScaleAbs(contours, contours);
cv::imshow("Laplacian", contours); cv::Mat sobelX, sobelY;
cv::Sobel(
image,
sobelX,
CV_16S, // 图像depth,输入8U,输出16S防止外溢
1, 0, // xorder, yorder
3, // 内核尺寸
1, 1 // 输出结果乘alpha加beta
);
cv::convertScaleAbs(sobelX, sobelX);
cv::imshow("Sobel_X", sobelX);
cv::Sobel(
image,
sobelY,
CV_8U,
0, 1,
3,
1, 1
);
cv::convertScaleAbs(sobelY, sobelY);
cv::imshow("Sobel_Y", sobelY);
cv::addWeighted(sobelX, 0.5, sobelY, 0.5, 0, contours);
cv::imshow("Sobel", contours);
}

『OpenCV3』滤波器边缘检测的更多相关文章

  1. 『OpenCV3』滤波器实现及使用滤波器降噪

    一.滤波器实现 我们实现这样一个基于拉普拉斯算子的滤波器核心,并使用它进行滤波,这可以做到锐化图像的效果, 0 -1 0 -1 5 -1 0 -1 0 首先我们完全手动的进行滤波,依赖指针操作, vo ...

  2. 『OpenCV3』霍夫变换原理及实现

    霍夫变换常用于检测直线特征,经扩展后的霍夫变换也可以检测其他简单的图像结构. 在霍夫变换中我们常用公式 ρ = x*cosθ + y*sinθ 表示直线,其中ρ是圆的半径(也可以理解为原点到直线的距离 ...

  3. 『OpenCV3』Harris角点特征_API调用及python手动实现

    一.OpenCV接口调用示意 介绍了OpenCV3中提取图像角点特征的函数: # coding=utf- import cv2 import numpy as np '''Harris算法角点特征提取 ...

  4. 『OpenCV3』基于色彩分割图片

    一.遍历图像实现色彩掩码 本节我们实现这样一个算法,我们指定某种颜色和一个阈值,根据输入图片生成一张掩码,标记符合的像素(和指定颜色的差异在阈值容忍内). 源代码如下,我们使用一个class完成这个目 ...

  5. 『OpenCV3』Mat简介

    Mat属性方法介绍:OpenCV2:Mat属性type,depth,step 推荐一套OpenCV入门博客:OpenCV探索 一.Mat Mat类用于表示一个多维的单通道或者多通道的稠密数组.能够用来 ...

  6. 『OpenCV3』处理视频&摄像头

    在opencv中,摄像头和视频文件并没有很大不同,都是一个可以read的数据源,使用cv2.VideoCapture(path).read()可以获取(flag,当前帧),对于每一帧,使用图片处理函数 ...

  7. 『OpenCV3』简单图片处理

    cv2和numpy深度契合,其图片读入后就是numpy.array,只不过dtype比较不常用而已,支持全部数组方法 数组既图片 import numpy as np import cv2 img = ...

  8. 『AngularJS』$location 服务

    项目中关于 $location的用法 简介 $location服务解析在浏览器地址栏中的URL(基于window.location)并且让URL在你的应用中可用.改变在地址栏中的URL会作用到$loc ...

  9. [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装

    [原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...

随机推荐

  1. 一年工作经验的大专生程序员(java后台)

    1.文章前言     作为18应届毕业大专生已工作一年,相信这也是大部分同届生的现状.       那么,一个萌新进入职场一年都经历了什么呢?在校那会我是挺好奇的.       这篇文章是根据自己一年 ...

  2. python基础之 while 逻辑运算符 格式化输出等

    1.while循环 while 条件: 循环体 while 条件: 循环体 else: 循环体 重点: 当条件为真的时候,就进入循环体,从上到下依次执行,执行完最后一条语句时,while并不是直接退出 ...

  3. MySql 创建索引原则

    https://blog.csdn.net/csdnones/article/details/50412603 为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引 ...

  4. Python基础(五) python装饰器使用

    这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 # -*- coding:gbk -*- '''示例1: 最简单的函数,表示调用了两次 ...

  5. Python使用中错误(持续更新.....)

    1.在使用requests发送请求,响应数据转成json提示,没有可解码的json 解决办法: 这是由于,发送请求的数据,存在错误,响应出错比如404 400,所以找不到可以解码的json 示例如下: ...

  6. python 爬虫-1

    买了本书在自学,我也不知道自己能学到什么地步,反正不用这个找工作,纯属爱好,有可能之后就会放弃 233333333.... 先来一个特别简单点的:将百度搜索主页  扒下来,并保存到一个文件里面 fir ...

  7. CentOS 7 MariaDB-MHA

    关于MHA    MHA(Master High Availability)是一款开源的mysql高可用程序,目前在mysql高可用方面是一个相对成熟的解决方案.MHA 搭建的前提是MySQL集群中已 ...

  8. java解答:有17个人围成一圈(编号0~16),从第0号的人开始从1报数,凡报到3的倍数的人离开圈子,然后再数下去,直到最后只剩下一个人为止,问此人原来的位置是多少号?

    package ttt; import java.util.HashMap; import java.util.Map.Entry; /** * 有17个人围成一圈(编号0~16),从第0号的人开始从 ...

  9. apache多站点vhost.conf配置

    #第1个站点的配置 <VirtualHost *:80> DocumentRoot "D:/phpStudy/WWW" ServerName localhost < ...

  10. Linux实现VLAN

    交换机的端口有两种配置模式:Access和Trunk. Access口:端口属于VLAN,VLAN ID 1~4096.直接与计算机网卡相连,流入该口的数据包都被打上VLAN的标签. Trunk口:允 ...