一、原理简介

边缘检测原理 - 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. WebDriver API--元素定位

    WebDriver属于Selenium体系中设计出来操作浏览器的一套API, 站在WebDriver的角度, 因为它针对多种编程语言都实现了一遍这套API,所以它可以支持多种编程语言: 站在编程语言的 ...

  2. springboot中通过cors协议解决跨域问题

    1.对于前后端分离的项目来说,如果前端项目与后端项目部署在两个不同的域下,那么势必会引起跨域问题的出现. 针对跨域问题,我们可能第一个想到的解决方案就是jsonp,并且以前处理跨域问题我基本也是这么处 ...

  3. android 知识汇总

    1.assets:不会在R.java文件下生成相应的标记,assets文件夹可以自己创建文件夹,必须使用AssetsManager类进行访问,存放到这里的资源在运行打包的时候都会打入程序安装包中, 2 ...

  4. 接口测试工具-Jmeter使用笔记(七:用户定义的变量)

    使用场景:一组API根据业务流程制作成测试脚本,想要移植到其他测试环境时,由于数据库发生了变更,有些初始化数据也相应发生了变化,例如环境地址.请求路径等等.博主甚至把服务器地址和接口的部分共同请求路径 ...

  5. java之jedis使用

    下载 依赖jar包下载 使用 # Redis settings redis.host=192.168.208.153 redis.port=6379 redis.pass=1234 redis.tim ...

  6. [Android] 转-RxJava+MVP+Retrofit+Dagger2+Okhttp大杂烩

    原文url: http://blog.iliyun.net/2016/11/20/%E6%A1%86%E6%9E%B6%E5%B0%81%E8%A3%85/ 这几年来android的网络请求技术层出不 ...

  7. CSS注意点

    案例: 实际开发中,这样写:

  8. flask重要点

    django与flask的区别 django: 大而全的框架,包含了很多组件,例如:ORM.form.ModelForm.session... flask: 轻量级的可扩展强的框架.有丰富的第三方组件 ...

  9. 微信小程序之mpvue+iview踩坑之旅

    因为之前参照微信的原生的文档写过一些小程序的demo,写的过程比较繁琐,后来出了美团的mpvue,可以直接使用vue开发,其他的不作对比,这篇文章记录一下踩坑之旅. 参照mpvue http://mp ...

  10. dotnet core命令

    dotnet run -----运行程序 dotnet publish -r centos-x64  -----发布程序 mkdri 文件名--->cd 文件名--->dotnet new ...