Sobel 边缘检测算子
转自: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_8U, ddepth = -1/CV_16S/CV_32F/CV_64F
src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F
src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F
src.depth() = CV_64F, ddepth = -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 边缘检测算子的更多相关文章
- 边缘检测算子和小波变换提取图像边缘【matlab】
Roberts边缘检测算子:根据一对互相垂直方向上的差分可用来计算梯度的原理,采用对角线方向相邻两像素之差. 小波变换的方法比较适用于展现夹带在正常信号中的瞬间反常现象,具有方向敏感性.所以可以边缘检 ...
- 边缘检测之Sobel检测算子
在讨论边缘算子之前,首先给出一些术语的定义: (1)边缘:灰度或结构等信息的突变处,边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像. (2)边缘点:图像中具有坐标[x,y],且处在 ...
- 各种边缘检测算子特点比较(canny)
canny 最好.但是容易把噪点误判为边界.sobel prewitt log 效果差不多.prewitt比sobel 去噪效果好.roberts马马虎虎.适合什么图片那得看图片的噪点情况,一般can ...
- 图像特征提取:Sobel边缘检测
前言 点和线是做图像分析时两个最重要的特征,而线条往往反映了物体的轮廓,对图像中边缘线的检测是图像分割与特征提取的基础.文章主要讨论两个实际工程中常用的边缘检测算法:Sobel边缘检测和Canny边缘 ...
- Sobel边缘检测算法(转载)
转载请注明出处: http://blog.csdn.net/tianhai110 索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰 ...
- OpenCV图像处理篇之边缘检测算子
OpenCV图像处理篇之边缘检测算子 转载: http://xiahouzuoxin.github.io/notes/ 3种边缘检测算子 一阶导数的梯度算子 高斯拉普拉斯算子 Canny算子 Open ...
- ###Canny边缘检测算子
开源中国. #@date: 2014-06-20 #@author: gerui #@email: forgerui@gmail.com 一.一阶微分边缘算子 1. 一阶微分边缘检测算子也称梯度边缘算 ...
- 数字图像处理之sobel边缘检测
在前两部文章介绍了几种边缘检测算法,和位图的内存结构.如果对前两篇文章已经理解透彻 了,那么本文将带你进入数字图像处理的世界. 本文通过C代码实现基本的sobel边缘检测,包括8个方向和垂直方向: 代 ...
- 基于FPGA的Sobel边缘检测的实现
前面我们实现了使用PC端上位机串口发送图像数据到VGA显示,通过MATLAB处理的图像数据直接是灰度图像,后面我们在此基础上修改,从而实现,基于FPGA的动态图片的Sobel边缘检测.中值滤波.Can ...
随机推荐
- Android Studio教程08-与其他app通信
目录 1.向另外一个应用发送用户 1.1. 构建隐含Intent 1.2. 验证是否存在接收Intent的应用 1.3. 启动具有Intent的Activity 2. 获取Activity的结果响应 ...
- linux环境快速编译安装python3.6
一.下载python3源码包 cd /tmp/wget https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz 二.下载python3编译的依 ...
- 应用 memcached 提升站点性能
减少读自数据库和数据源 开源 memcached 工具是一个用来存储常用信息的缓存,有了它,您便无需从缓慢的资源,比如磁盘或数据库,加载(并处理)信息了.该工具可部署在专用的情况下,也可作为用完现有环 ...
- Java 8 新特性7-方法引用、继承
(原) 方法引用: 方法引用有4种: 1.静态方法引用:类名::静态方法名 在java中,对集合的排序,我们常用java提供的 Collections.sort(List<T> list, ...
- 微软是如何重写C#编译器并使它开源的
译者:王亮作者:Mads Torgersen (C# Language PM at Microsoft)原文:http://t.cn/EPOG96O 译者的一些话: 看了大家的评论,有园友说我翻译的不 ...
- aelf帮助C#工程师10分钟零门槛搭建DAPP&私有链开发环境
aelf是一个可扩展的去中心化云计算区块链平台,支持高性能合约并行执行.原生多链数据交互.存储使用高性能分布式数据库. aelf整个系统可以在windows.osx及linux运行,团队在osx环境下 ...
- Ajax 简单的实例代码
<!DOCTYPE HTML><html><head><script src="http://libs.baidu.com/jquery/2.0.0 ...
- jQuery对页面的操作
一.对元素内容和值进行操作 1.对元素内容操作 [text()]:获取值. [text(val)]:获取并修改值. [html()]:获取值. [html(val)]:获取并修改值,与text的区别在 ...
- [模板] 多项式: 乘法/求逆/分治fft/微积分/ln/exp/幂
多项式 代码 const int nsz=(int)4e5+50; const ll nmod=998244353,g=3,ginv=332748118ll; //basic math ll qp(l ...
- UVA 10618 Tango Tango Insurrection
https://vjudge.net/problem/UVA-10618 题目 你想学着玩跳舞机.跳舞机的踏板上有4个箭头:上.下.左.右.当舞曲开始时,屏幕上会有一些箭头往上移动.当向上移动箭头与顶 ...