Sobel导数
Sobel 导数
原理
Note
以下内容来自于Bradski和Kaehler的大作: Learning OpenCV .
上面两节我们已经学习了卷积操作。一个最重要的卷积运算就是导数的计算(或者近似计算).
为什么对图像进行求导是重要的呢? 假设我们需要检测图像中的 边缘 ,如下图:
你可以看到在 边缘 ,相素值显著的 改变 了。表示这一 改变 的一个方法是使用 导数 。 梯度值的大变预示着图像中内容的显著变化。
用更加形象的图像来解释,假设我们有一张一维图形。下图中灰度值的”跃升”表示边缘的存在:
使用一阶微分求导我们可以更加清晰的看到边缘”跃升”的存在(这里显示为高峰值)
从上例中我们可以推论检测边缘可以通过定位梯度值大于邻域的相素的方法找到(或者推广到大于一个阀值).
更加详细的解释,请参考Bradski 和 Kaehler的 Learning OpenCV 。
Sobel算子
- Sobel 算子是一个离散微分算子 (discrete differentiation operator)。 它用来计算图像灰度函数的近似梯度。
- Sobel 算子结合了高斯平滑和微分求导。
计算
假设被作用图像为 :
在两个方向求导:
水平变化: 将
与一个奇数大小的内核
进行卷积。比如,当内核大小为3时,
的计算结果为:
垂直变化: 将:math:I 与一个奇数大小的内核
进行卷积。比如,当内核大小为3时,
的计算结果为:
在图像的每一点,结合以上两个结果求出近似 梯度:
有时也用下面更简单公式代替:
源码
- 本程序做什么?
- 使用 Sobel算子 产生的输出图像上,检测到的亮起的 边缘 相素散布在更暗的背景中。
- 下面是本教程的源码,你也可以从 here 下载
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h> using namespace cv; /** @function main */
int main( int argc, char** argv )
{ Mat src, src_gray;
Mat grad;
char* window_name = "Sobel Demo - Simple Edge Detector";
int scale = 1;
int delta = 0;
int ddepth = CV_16S; int c; /// 装载图像
src = imread( argv[1] ); if( !src.data )
{ return -1; } GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT ); /// 转换为灰度图
cvtColor( src, src_gray, CV_RGB2GRAY ); /// 创建显示窗口
namedWindow( window_name, CV_WINDOW_AUTOSIZE ); /// 创建 grad_x 和 grad_y 矩阵
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y; /// 求 X方向梯度
//Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_x, abs_grad_x ); /// 求Y方向梯度
//Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_y, abs_grad_y ); /// 合并梯度(近似)
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad ); imshow( window_name, grad ); waitKey(0); return 0;
}
解释
首先申明变量:
Mat src, src_gray;
Mat grad;
char* window_name = "Sobel Demo - Simple Edge Detector";
int scale = 1;
int delta = 0;
int ddepth = CV_16S;装载原图像 src:
src = imread( argv[1] ); if( !src.data )
{ return -1; }第一步对原图像使用 GaussianBlur 降噪 ( 内核大小 = 3 )
GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );
将降噪后的图像转换为灰度图:
cvtColor( src, src_gray, CV_RGB2GRAY );
第二步,在 x 和 y 方向分别”求导“。 为此,我们使用函数 Sobel :
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y; /// 求 X方向梯度
Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
/// 求 Y方向梯度
Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );该函数接受了以下参数:
- src_gray: 在本例中为输入图像,元素类型 CV_8U
- grad_x/grad_y: 输出图像.
- ddepth: 输出图像的深度,设定为 CV_16S 避免外溢。
- x_order: x 方向求导的阶数。
- y_order: y 方向求导的阶数。
- scale, delta 和 BORDER_DEFAULT: 使用默认值
注意为了在 x 方向求导我们使用:
,
. 采用同样方法在 y 方向求导。
将中间结果转换到 CV_8U:
convertScaleAbs( grad_x, abs_grad_x );
convertScaleAbs( grad_y, abs_grad_y );将两个方向的梯度相加来求取近似 梯度 (注意这里没有准确的计算,但是对我们来讲已经足够了)。
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );
最后,显示结果:
imshow( window_name, grad );
结果
这里是将Sobel算子作用于 lena.jpg 的结果:
Sobel导数的更多相关文章
- 2.7 Sobel导数
OpenCV函数 Sobel(src_gray,grad_x/grad_y,ddepth,x_order,y_order,scale,delta,BORDER_DEFAULT ) Scharr( ) ...
- OpenCV Sobel 导数
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #i ...
- opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测
opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测 这章讲了 sobel算子 scharr算子 Laplacion拉普拉斯算子 图像深度问题 Canny检测 图像梯度 sobel算子 ...
- 2.opencv图像处理常用操作
图像的平滑处理 平滑,也称 模糊, 平滑处理时需要用到一个滤波器 .滤波器想象成一个包含加权系数的窗口,这个加权系数也叫做核或者模版. // 图像平滑处理分而学之.cpp : 定义控制台应用程序的入口 ...
- 【OpenCV新手教程第14】OpenCVHough变换:霍夫变换线,霍夫变换圆汇编
本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26977557 作者:毛星云(浅墨) ...
- SciPy模块应用
1.图像模糊 图像的高斯模糊是非常经典的图像卷积例子.本质上,图像模糊就是将(灰度)图像I 和一个高斯核进行卷积操作:,其中是标准差为σ的二维高斯核.高斯模糊通常是其他图像处理操作的一部分,比如图像 ...
- [OpenCV-Python] OpenCV 中的图像处理 部分 IV (二)
部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 16 图像平滑 目标 • 学习使用不同的低通滤波器对图像进行模糊 • 使用自定义的滤波器对图像进行卷积(2D 卷 ...
- [OpenCV-Python] OpenCV 中机器学习 部分 VIII
部分 VIII机器学习 OpenCV-Python 中文教程(搬运)目录 46 K 近邻(k-Nearest Neighbour ) 46.1 理解 K 近邻目标 • 本节我们要理解 k 近邻(kNN ...
- OpenCV常用库函数[典]
一.core 模块 1.Mat - 基本图像容器 Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是 ...
随机推荐
- 一家O2O社区App公司的随笔
近两年,O20是业内最火爆的关键词之一,去年拿到1亿天使投资的叮咚小区都引起了各方的关注. 一个月之前我入职了一家以做O2O社区产品的创业公司,此文会把这段时间和后边所见所想都写出来,总结创业公司和创 ...
- inside when() you don't call method on mock but on some other object
错误原因:调用静态方法,要事先引入静态类,否则mock的时候会默认为测试的类 解决方法:@PrepareForTest({SecurityContextHolder.class})引入静态类 注:@P ...
- HTML DOM节点的增删改查
上篇博客中,我们已经初步接触了DOM基础,可是我们学习是为了可以更好地应用,今天我们就来看看DOM节点的增删改查. 无论在哪里,我们想要操作一个东西,总是应该先去获得它.那么我们怎么获得呢? HTML ...
- 解决Tomcat下连接Oracle报错"Error while registering Oracle JDBC Diagnosability MBean."
Tomcat不失为一个好的开发学习容器,但使用Oracle 11g自带的JDBC驱动ojdbc6.jar和JDK6一起运行的时候,特别是和spring框架一起使用会报错:SEVERE: Error w ...
- 2017年Android百大框架排行榜(转)
一.榜单介绍 排行榜包括四大类: 单一框架:仅提供路由.网络层.UI层.通信层或其他单一功能的框架 混合开发框架:提供开发hybrid app.h5与webview结合能力.web app能力的框架 ...
- 002android初级篇之ViewPager及PagerSlidingTabStrip listview的使用
002android初级篇之ViewPager及PagerSlidingTabStrip listview的使用 ViewPager ViewPager类直接继承了ViewGroup类,所有它是一个容 ...
- 五分钟上手Git
团队开发中.遵循一个合理.清晰的Git使用流程.是非常重要的.否则,每一个人都提交一堆杂乱无章的commit,项目非常快就会变得难以协调和维护.以下是ThoughtBot 的Git使用规范流程.我从中 ...
- Android string.xml 显示特殊符号
项目中要在string.xml 中显示特殊符号,如@号冒号等,直接写肯定不行啦..只能考虑使用ASCII码进行显示: 省略号 …@号 @:号 :空格 以下为常见的ASCII十进制交换编码: --& ...
- ASIHTTP 框架,同步、 异步请求、 上传 、 下载
ASIHTTPRequest详解 ASIHTTPRequest 是一款极其强劲的 HTTP 访问开源项目.让简单的 API 完成复杂的功能,如:异步请求,队列请求,GZIP 压缩,缓存,断点续传,进度 ...
- images have the “stationarity” property, which implies that features that are useful in one region are also likely to be useful for other regions.
Convolutional networks may include local or global pooling layers[clarification needed], which combi ...