转自:http://blog.csdn.net/xiaqunfeng123/article/details/17302003

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

图像边缘,相素值会发生显著的变化了。表示这一改变的一个方法是使用 导数 。 梯度值的大变预示着图像中内容的显著变化。用更加形象的图像来解释,假设我们有一张一维图形。下图2中灰度值的”跃升”表示边缘的存在,图3中使用一阶微分求导我们可以更加清晰的看到边缘”跃升”的存在。

图1、lena.jpg

图2、像素一维图形

图3、一阶导数

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

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

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

在图像的每一点,结合以上两个结果求出近似 梯度 ,如图4c:

图4a

图4b

图4c

因为Sobel算子只是求取了导数的近似值,当内核大小为时,以上Sobel内核可能产生比较明显的误差。为解决这一问题,OpenCV提供了 Scharr 函数,但该函数仅作用于大小为3的内核,该函数的运算与Sobel函数一样快,但结果却更加精确。

两种实现版本:

C 版本:

cvSobel ( const cvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size =3 )

src,  dst 分别是源图像和目标图像,xorder ,yorder – 分别为x,y方向导数运算参数,可取0,1,2  。aperture_size是方形滤波器的宽,是小于7的奇数。

具体见《Learning OpenCV》那本书,P.170页

下面是代码,比较简单:

#include <highgui.h>
#include <cv.h> using namespace cv;
using namespace std; int main(int argc, char ** argv)
{
IplImage* src, *dstx,*dsty,*dst; src = cvLoadImage( "car.png", );
dst = cvCreateImage( cvGetSize( src ), IPL_DEPTH_16S, );
dstx = cvCreateImage( cvGetSize( src ), IPL_DEPTH_16S, );
dsty = cvCreateImage( cvGetSize( src ), IPL_DEPTH_16S, ); cvNamedWindow( "src" );
cvNamedWindow( "sobel" ); cvShowImage( "src", src ); cvSobel( src, dstx, , , ); //sobel
cvSobel( src, dsty, , , );
cvAddWeighted(dstx,0.5,dsty,0.5,,dst); cvShowImage( "sobel", dst ); cvWaitKey();
cvReleaseImage( &src );
cvReleaseImage( &dst ); return ;
}

效果图:

C++版本:

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

C++:   void Sobel(  InputArray src ,  OutputArray dst,  int ddepth,  int dx,  int dy,  int ksize=3,

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

各参数的意义如下:

src – 输入图像。dst – 输出图像,与输入图像同样大小,拥有同样个数的通道。

ddepth –输出图片深度;下面是输入图像支持深度和输出图像支持深度的关系:

src.depth() = CV_8Uddepth = -1/CV_16S/CV_32F/CV_64F

src.depth() = CV_16U/CV_16Sddepth = -1/CV_32F/CV_64F

src.depth() = CV_32Fddepth = -1/CV_32F/CV_64F

src.depth() = CV_64Fddepth = -1/CV_64F

当 ddepth为-1时, 输出图像将和输入图像有相同的深度。输入8位图像则会截取顶端的导数。

xorder – x方向导数运算参数。yorder – y方向导数运算参数。

ksize – Sobel内核的大小,可以是:1,3,5,7。  注意:只可以是小于7 的奇数

scale – 可选的缩放导数的比例常数。delta – 可选的增量常数被叠加到导数中。borderType – 用于判断图像边界的模式。

下面是程序:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h> using namespace cv;
using namespace std; int main( int argc, char** argv )
{
Mat src, src_gray;
Mat grad;
char* window_name = "求解梯度";
int scale = ;
int delta = ;
int ddepth = CV_16S; src = imread( "car.png" );
if( !src.data )
{
return -;
}
//高斯模糊
GaussianBlur( src, src, Size(,), , , BORDER_DEFAULT );
//转成灰度图
cvtColor( src, src_gray,CV_RGB2GRAY ); namedWindow( window_name, CV_WINDOW_AUTOSIZE ); Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y;
//x方向梯度计算
Sobel( src_gray, grad_x, ddepth, , , , scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_x, abs_grad_x );
//y方向梯度计算
Sobel( src_gray, grad_y, ddepth, , , , scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_y, abs_grad_y );
//加权和
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, , grad ); imshow( window_name, grad ); waitKey();
return ;
}

如果要用Scharr滤波器的话,把Sobel那行代码替换掉就好了:

Scharr( src_gray, grad_x, ddepth, , , scale, delta, BORDER_DEFAULT );
Scharr( src_gray, grad_x, ddepth, , , scale, delta, BORDER_DEFAULT );

效果图:

参考资料:http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html

转载请注明出处:http://blog.csdn.net/xiaqunfeng123

Sobel 边缘检测算子的更多相关文章

  1. 边缘检测算子和小波变换提取图像边缘【matlab】

    Roberts边缘检测算子:根据一对互相垂直方向上的差分可用来计算梯度的原理,采用对角线方向相邻两像素之差. 小波变换的方法比较适用于展现夹带在正常信号中的瞬间反常现象,具有方向敏感性.所以可以边缘检 ...

  2. 边缘检测之Sobel检测算子

    在讨论边缘算子之前,首先给出一些术语的定义: (1)边缘:灰度或结构等信息的突变处,边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像. (2)边缘点:图像中具有坐标[x,y],且处在 ...

  3. 各种边缘检测算子特点比较(canny)

    canny 最好.但是容易把噪点误判为边界.sobel prewitt log 效果差不多.prewitt比sobel 去噪效果好.roberts马马虎虎.适合什么图片那得看图片的噪点情况,一般can ...

  4. 图像特征提取:Sobel边缘检测

    前言 点和线是做图像分析时两个最重要的特征,而线条往往反映了物体的轮廓,对图像中边缘线的检测是图像分割与特征提取的基础.文章主要讨论两个实际工程中常用的边缘检测算法:Sobel边缘检测和Canny边缘 ...

  5. Sobel边缘检测算法(转载)

    转载请注明出处:  http://blog.csdn.net/tianhai110 索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰 ...

  6. OpenCV图像处理篇之边缘检测算子

    OpenCV图像处理篇之边缘检测算子 转载: http://xiahouzuoxin.github.io/notes/ 3种边缘检测算子 一阶导数的梯度算子 高斯拉普拉斯算子 Canny算子 Open ...

  7. ###Canny边缘检测算子

    开源中国. #@date: 2014-06-20 #@author: gerui #@email: forgerui@gmail.com 一.一阶微分边缘算子 1. 一阶微分边缘检测算子也称梯度边缘算 ...

  8. 数字图像处理之sobel边缘检测

    在前两部文章介绍了几种边缘检测算法,和位图的内存结构.如果对前两篇文章已经理解透彻 了,那么本文将带你进入数字图像处理的世界. 本文通过C代码实现基本的sobel边缘检测,包括8个方向和垂直方向: 代 ...

  9. 基于FPGA的Sobel边缘检测的实现

    前面我们实现了使用PC端上位机串口发送图像数据到VGA显示,通过MATLAB处理的图像数据直接是灰度图像,后面我们在此基础上修改,从而实现,基于FPGA的动态图片的Sobel边缘检测.中值滤波.Can ...

随机推荐

  1. 让 Windows7 - 64bit 支持 VC++ 6.0 的解决方法(无法启动此程序,因为计算机中丢失 MSVCRTD.dll。尝试重新安装该程序以解决此问题)

    源地址:https://www.cnblogs.com/poissonnotes/p/4372136.html 无法启动此程序,因为计算机中丢失 MSVCRTD.dll.尝试重新安装该程序以解决此问题 ...

  2. 做为一个Python程序员的基本素养

    今天在学习的过程中,明白了一些不是Python标准所必须要做的事情,二是做为一个合格的Python程序员应该所遵从的一些规范 分享给大家,有不足的地方请大家指正,此下是我学习的一点心得: 1.在给变量 ...

  3. hello随笔

    初次来到博客园,都试一下 我明白了,随笔就是博客咯.日记自对自己可见.再试试分类吧

  4. 【Teradata SQL】创建数据库和表

    1.数据库perm大小为10G Create database testbase as perm=10E9,spool=10E9; 2.创建物理表 create multiset table stg( ...

  5. .NET ORM框架之NHibernate

    这段时间一直使用NHibernate,今天抽空总结一下. 1.什么是NHibernate? NHibernate是一个面向.NET环境的对象/关系数据库映射工具.对象/关系数据库映射(object/r ...

  6. AQS框架源码分析-AbstractQueuedSynchronizer

    前言:AQS框架在J.U.C中的地位不言而喻,可以说没有AQS就没有J.U.C包,可见其重要性,因此有必要对其原理进行详细深入的理解. 1.AQS是什么 在深入AQS之前,首先我们要搞清楚什么是AQS ...

  7. IDEA 相关整理

    插件部分 Lombok 日志不定义

  8. 日志级别的选择:Debug、Info、Warn、Error

    日志信息分类 1.等级由低到高:debug<info<warn<Error: 2.区别: debug 级别最低,可以随意的使用于任何觉得有利于在调试时更详细的了解系统运行状态的东东: ...

  9. Ubuntu16.04中php如何切换版本

    其实就是一条Linux命令,如下: sudo update-alternatives --config php 会出现下面选项: There are choices for the alternati ...

  10. python之log

    #!/usr/bin/python # -*- coding: UTF- -*- ''' ''' import logging # 设置输出文件.文件格式和日志级别 logging.basicConf ...