https://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html

OpenCV 2.4 C++ 边缘梯度计算 --- sobel 使用说明

Sobel算子

Sobel 算子是一个离散微分算子 (discrete differentiation operator)。 它结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。

一.基础知识介绍

[1]图像的边缘

图像的边缘从数学上是如何表示的呢?

图像的边缘上,邻近的像素值应当显著地改变了。而在数学上,导数是表示改变快慢的一种方法,一个函数在某一点的导数描述了这个函数在这一点附近的变化率。

梯度可谓是多元函数的偏导,表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。。

用更加形象的图像来解释,假设我们有一张一维图形。下图中灰度值的“跃升”表示边缘的存在:

    

使用一阶微分求导我们可以更加清晰的看到边缘“跃升”的存在(这里显示为高峰值):

  

由此我们可以得出:边缘可以通过定位梯度值大于邻域的相素的方法找到。

[2]卷积

卷积可以近似地表示求导运算。

那么卷积是什么呢?

卷积是在每一个图像块与某个算子(核)之间进行的运算。

核呢?

核就是一个固定大小的数值数组。该数组带有一个锚点 ,一般位于数组中央。

可是这怎么运算啊?

假如你想得到图像的某个特定位置的卷积值,可用下列方法计算:

  1. 将核的锚点放在该特定位置的像素上,同时,核内的其他值与该像素邻域的各像素重合;
  2. 将核内各值与相应像素值相乘,并将乘积相加;
  3. 将所得结果放到与锚点对应的像素上;
  4. 对图像所有像素重复上述过程。

用公式表示上述过程如下:

    

在图像边缘的卷积怎么办呢?

计算卷积前,OpenCV通过复制源图像的边界创建虚拟像素,这样边缘的地方也有足够像素计算卷积了。

二.Sobel的卷积实现

Sobel是采用卷积的计算方法实现的。假设被作用的图像为 ,在两个方向上求导:

水平变化求导:将  与一个奇数大小的内核  进行卷积。比如,当内核大小为3时,  的计算结果为图1

垂直变化求导:将 I 与一个奇数大小的内核  进行卷积。比如,当内核大小为3时,  的计算结果为图2

在图像的每一点,结合以上两个结果求出近似梯度大小 ,如图3

计算梯度方向,如图4   (如果以上的角度Θ等于零,即代表图像该处拥有纵向边缘,左方较右方暗)

图1                                  图2                                    图3                         图4

三.Code

先来看一下C++下 Sobel 的定义

cv:Sobel(  InputArray src ,  OutputArray dst,  int ddepth,  int dx,  int dy,  int ksize=,   

             double scale=,double delta=,intborderType=BORDER_DEFAULT )

各参数的意义如下:

src – 输入图像。
dst – 输出图像,与输入图像同样大小,拥有同样个数的通道。
ddepth –输出图片深度;下面是输入图像支持深度和输出图像支持深度的关系: src.depth() = CV_8U, ddepth = -/CV_16S/CV_32F/CV_64F src.depth() = CV_16U/CV_16S, ddepth = -/CV_32F/CV_64F src.depth() = CV_32F, ddepth = -/CV_32F/CV_64F src.depth() = CV_64F, ddepth = -/CV_64F 当 ddepth为-1时, 输出图像将和输入图像有相同的深度。输入8位图像则会截取顶端的导数。 xorder – x方向导数运算参数。
yorder – y方向导数运算参数。
ksize – Sobel内核的大小,可以是:,,,。 注意:只可以是小于7 的奇数
scale – 可选的缩放导数的比例常数。
delta – 可选的增量常数被叠加到导数中。
borderType – 用于判断图像边界的模式。
#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 = ;
int delta = ;
int ddepth = CV_16S; int c; /// Load an image
src = imread( argv[] ); if( !src.data )
{ return -; }

///高斯模糊---apply a GaussianBlur to our image to reduce the noise ( kernel size = 3 )
GaussianBlur( src, src, Size(,), , , BORDER_DEFAULT ); /// Convert it to gray
cvtColor( src, src_gray, CV_BGR2GRAY ); /// Create window
namedWindow( window_name, CV_WINDOW_AUTOSIZE );

///calculate the “derivatives” in x and y directions
/// Generate grad_x and grad_y
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y;
/// Gradient X
//Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
Sobel( src_gray, grad_x, ddepth, , , , scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_x, abs_grad_x ); //convert our partial results back to CV_8U
/// Gradient Y
//Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
Sobel( src_gray, grad_y, ddepth, , , , scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_y, abs_grad_y ); /// Total Gradient (approximate近似)---we try to approximate the gradient by adding both directional gradients
(note that this is not an exact calculation at all! but it is good for our purposes).
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, , grad ); imshow( window_name, grad ); waitKey(); return ;
}

Sobel Derivatives的更多相关文章

  1. 彻底理解数字图像处理中的卷积-以Sobel算子为例

    彻底理解数字图像处理中的卷积-以Sobel算子为例 作者:FreeBlues 修订记录 2016.08.04 初稿完成 概述 卷积在信号处理领域有极其广泛的应用, 也有严格的物理和数学定义. 本文只讨 ...

  2. sobel 使用说明

    转自http://www.cnblogs.com/justany/archive/2012/11/23/2782660.html OpenCV 2.4+ C++ 边缘梯度计算 2012-11-23 0 ...

  3. OpenCV4系列之图像梯度和边缘检测

    在图像处理中,求解图像梯度是常用操作. Sobel算子 Calculates the first, second, third, or mixed image derivatives using an ...

  4. 【OpenCV】边缘检测:Sobel、拉普拉斯算子

    推荐博文,博客.写得很好,给个赞. Reference Link : http://blog.csdn.net/xiaowei_cqu/article/details/7829481 一阶导数法:梯度 ...

  5. OpenCV2马拉松第14圈——边缘检測(Sobel,prewitt,roberts)

    收入囊中 差分在边缘检測的角色 Sobel算子 OpenCV sobel函数 OpenCV Scharr函数 prewitt算子 Roberts算子 葵花宝典 差分在边缘检測究竟有什么用呢?先看以下的 ...

  6. EasyPR源码剖析(4):车牌定位之Sobel算子定位

    一.简介 sobel算子主要是用于获得数字图像的一阶梯度,常见的应用是边缘检测. Ⅰ.水平变化: 将 I 与一个奇数大小的内核进行卷积.比如,当内核大小为3时, 的计算结果为: Ⅱ.垂直变化: 将: ...

  7. EasyPR--开发详解(3)高斯模糊、灰度化和Sobel算子

    在上篇文章中我们了解了PlateLocate的过程中的所有步骤.在本篇文章中我们对前3个步骤,分别是高斯模糊.灰度化和Sobel算子进行分析. 一.高斯模糊 1.目标 对图像去噪,为边缘检测算法做准备 ...

  8. sobel算子的一些细节

    1. 形式 Gy 上下颠倒的 (*A表示卷积图像,忽略先): 看得出来,sobel算子感觉并不统一,特别是方向,我们知道matlab的图像格式是,x轴从左到右,y轴从上到下,原点在左上角. 所以,第二 ...

  9. sobel算子原理及opencv源码实现

    sobel算子原理及opencv源码实现 简要描述 sobel算子主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测. 原理 算子使用两个33的矩阵(图1)算子使用两个33的矩阵(图1)去 ...

随机推荐

  1. 一个rcu回调导致的简单死锁

    在自有模块的处理中,我们设计了一个内核线程去做gc, 但同时,我们又用到了rcu,rcu中也会去抢gc的锁,由于该锁用的spin_lock,而不是spin_lock_bh,并没有关软中断,所以在rcu ...

  2. Mybatis高级应用-2

    文章内容简介 1.回顾 2.Mybatis配置文件解析 3.Mybatis映射文件解析 ResultMap标签使用 自定义返回值处理(Map) 关联映射 主键映射 一.回顾 Mybatis是ORM(o ...

  3. 如何进行SQL排序

    order by 语法如下: SELECT "栏位名" FROM "表格名" [WHERE "条件"] ORDER BY "栏位名 ...

  4. scala case类

    case类 case class Person(name:String) case 类有如下特点: 1. 构造参数默认是 val 的. 2. case 类实例化对象的时候,不需要 new 关键字.因为 ...

  5. Logo tools

    http://www.cilogo.com/LOGO/

  6. js(鼠标键盘拖动事件)

    拖动事件是h5(HTML5的) 1:draggable(true) 2:拖动源 ondragstart ,ondragend 3:目的地 ondraglenter,ondragover,ondragl ...

  7. python批量操作Linux服务器脚本,ssh密码登录(执行命令、上传、下载)(一)

     -*-          paramiko.util.log_to_file(         ssh = paramiko.SSHClient()          ssh.set_missing ...

  8. hbase高可用集群部署(cdh)

    一.概要 本文记录hbase高可用集群部署过程,在部署hbase之前需要事先部署好hadoop集群,因为hbase的数据需要存放在hdfs上,hadoop集群的部署后续会有一篇文章记录,本文假设had ...

  9. mysql 触发器介绍

    create trigger triggerName   after/before insert/update/delete on tableName  for each row   --这句话在my ...

  10. html----h1-6标签

    Html的标题标签h1-h6种选择,从大到小:默认上下margin一样,靠左,不好改变:能用定位改变. 1.<h1></h1> display:block; font-size ...