『OpenCV3』滤波器边缘检测
一、原理简介
边缘检测原理 - 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』滤波器边缘检测的更多相关文章
- 『OpenCV3』滤波器实现及使用滤波器降噪
一.滤波器实现 我们实现这样一个基于拉普拉斯算子的滤波器核心,并使用它进行滤波,这可以做到锐化图像的效果, 0 -1 0 -1 5 -1 0 -1 0 首先我们完全手动的进行滤波,依赖指针操作, vo ...
- 『OpenCV3』霍夫变换原理及实现
霍夫变换常用于检测直线特征,经扩展后的霍夫变换也可以检测其他简单的图像结构. 在霍夫变换中我们常用公式 ρ = x*cosθ + y*sinθ 表示直线,其中ρ是圆的半径(也可以理解为原点到直线的距离 ...
- 『OpenCV3』Harris角点特征_API调用及python手动实现
一.OpenCV接口调用示意 介绍了OpenCV3中提取图像角点特征的函数: # coding=utf- import cv2 import numpy as np '''Harris算法角点特征提取 ...
- 『OpenCV3』基于色彩分割图片
一.遍历图像实现色彩掩码 本节我们实现这样一个算法,我们指定某种颜色和一个阈值,根据输入图片生成一张掩码,标记符合的像素(和指定颜色的差异在阈值容忍内). 源代码如下,我们使用一个class完成这个目 ...
- 『OpenCV3』Mat简介
Mat属性方法介绍:OpenCV2:Mat属性type,depth,step 推荐一套OpenCV入门博客:OpenCV探索 一.Mat Mat类用于表示一个多维的单通道或者多通道的稠密数组.能够用来 ...
- 『OpenCV3』处理视频&摄像头
在opencv中,摄像头和视频文件并没有很大不同,都是一个可以read的数据源,使用cv2.VideoCapture(path).read()可以获取(flag,当前帧),对于每一帧,使用图片处理函数 ...
- 『OpenCV3』简单图片处理
cv2和numpy深度契合,其图片读入后就是numpy.array,只不过dtype比较不常用而已,支持全部数组方法 数组既图片 import numpy as np import cv2 img = ...
- 『AngularJS』$location 服务
项目中关于 $location的用法 简介 $location服务解析在浏览器地址栏中的URL(基于window.location)并且让URL在你的应用中可用.改变在地址栏中的URL会作用到$loc ...
- [原创] 【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 ...
随机推荐
- MongoDB "$" 字符 下标位置
我们可以修改列表里面元素的名字 例如: 修改age=34的数据,hobby里面的"足球"改为"网球" }) { "_id" : Object ...
- dyld_shared_cache_extract_dylibs failed
文章来源:https://www.jianshu.com/p/e276a784fbee s.png 数据线插上手机 Xcode->window 3.png 2.png 点击Unpai ...
- Cocos 2dx项目lua调用OC出现卡死但不闪退的坑
最近新上线的一个游戏,发现线上游戏有部分功能在点击的时候出现了没有反应的情况.通过调试源码,发现是原生OC的代码出现了崩溃,但是比较奇怪的是线上的Bugly没有任何记录,这个功能属于高频高能,而且又是 ...
- Redis入门到高可用(十五)—— HyperLogLog
一.简介 二.API Demo 三.使用经验
- 【LeetCode每天一题】Spiral Matrix(螺旋打印数组)
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...
- C 二叉查找树的基本操作
最近研究一下二叉树排序问题,找到的资料还真是五花八门,说得也是千奇百怪. 分析一下原因,还是因为数的特性,造成结果的不唯一性造成的大家看了很多,似乎都有理,好像明白了,一综合又糊涂了的结果. 我这里给 ...
- 台式电脑、笔记本快捷选择启动项Boot 快捷键大全
我们在安装系统时,会去设置电脑是从硬盘启动.U盘启动.光驱启动.网卡启动. 一般设置的方法有两种:一种是进BIOS主板菜单设置启动项顺序:另一种就是我在这里要介绍的快捷选择启动项. 以下是网友整理的各 ...
- 一:window环境,LaTex快速安装(简单易懂)
一. 下载 清华开源软件镜像:点我下载 在线安装很容易失败,所以咱们选择ISO的~ 二. 安装 解压texlive2018.iso文件,并使用管理员权限打开install-tl-windo ...
- ORA-00907: 缺失右括号,原因及解决办法整理
ORA-00907: 缺失右括号,原因及解决办法整理 1 union all中order by 导致缺失右括号 在有union all的子查询中使用了order by,会导致缺失右括号的错误,事实上在 ...
- DataGridView 访问任意行不崩溃
int index= this.dataGridView1.rows.Add(); 先执行这行代码,然后访问任意行,不崩溃, 赋值不存在的行,只是不显示,或者无值. 什么原理呢? 一些其他 priva ...