边缘检测之Sobel检测算子
在讨论边缘算子之前,首先给出一些术语的定义:
(1)边缘:灰度或结构等信息的突变处,边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像。
(2)边缘点:图像中具有坐标[x,y],且处在强度显著变化的位置上的点。
(3)边缘段:对应于边缘点坐标[x,y]及其方位 ,边缘的方位可能是梯度角。
二、Sobel算子的基本原理
Sobel算子是一阶导数的边缘检测算子,在算法实现过程中,通过3×3模板作为核与图像中的每个像素点做卷积和运算,然后选取合适的阈值以提取边缘。
一个特殊卷积所实现的功能是由卷积核的形式决定的。这个核本质上是一个大小固定、由数值参数构成的数组,数组的参考点(anchor point)通常位于数组的中心。数组的大小成为核支撑。单就技术而言,核支撑实际上仅仅由核数组的非0部分组成。对图像的卷积,首先将核的参考点定位到图像的第一个像素点,核的其余元素覆盖图像中其相对应的局部像素点。对于每一个核点,我们可以得到这个点的核值以及图像中相应图像点的值,将这些值相乘并求和,并将这个结果放在与输入图像参考点所相对应的位置。通过在整个图像上扫描卷积核,对图像的每个点重复此操作。
索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一阶离散性差分算子,用来运算图像亮度函数的灰度值近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量。
Sobel卷积因子为:

该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像灰度值,其公式如下:

具体计算如下:
Gx = (-1)*f(x-1, y-1) + 0*f(x,y-1) + 1*f(x+1,y-1)
+(-2)*f(x-1,y) + 0*f(x,y)+2*f(x+1,y)
+(-1)*f(x-1,y+1) + 0*f(x,y+1) + 1*f(x+1,y+1)
= [f(x+1,y-1)+2*f(x+1,y)+f(x+1,y+1)]-[f(x-1,y-1)+2*f(x-1,y)+f(x-1,y+1)]
Gy =1* f(x-1, y-1) + 2*f(x,y-1)+ 1*f(x+1,y-1)
+0*f(x-1,y) 0*f(x,y) + 0*f(x+1,y)
+(-1)*f(x-1,y+1) + (-2)*f(x,y+1) + (-1)*f(x+1, y+1)
= [f(x-1,y-1) + 2f(x,y-1) + f(x+1,y-1)]-[f(x-1, y+1) + 2*f(x,y+1)+f(x+1,y+1)]
其中f(a,b), 表示图像(a,b)点的灰度值;
图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小:

通常,为了提高效率 使用不开平方的近似值:

如果梯度G大于某一阀值 则认为该点(x,y)为边缘点。
然后可用以下公式计算梯度方向:

Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高。当对精度要求不是很高时,是一种较为常用的边缘检测方法。
Sobel算子算法的优点是计算简单,速度快。但是由于只采用了2个方向的模板,只能检测水平和垂直方向的边缘,因此这种算法对于纹理较为复杂的图像,其边缘检测效果就不是很理想。该算法认为:凡灰度新值大于或等于阈值的像素点时都是边缘点。这种判断欠合理,会造成边缘点的误判,因为许多噪声点的灰度值也很大。
#include <opencv2/opencv.hpp> int main(int argc, char **argv)
{
//定义显示窗口的名字
const char *ptrSrcImageWindowTitle = "SrcImage";
const char *ptrGrayImageWindowTitle = "GrayImage";
const char *ptrDesImageWindowTitle = "DesImage";
//载入图片并且分配图片所需内存
IplImage *pSrcImage = cvLoadImage("8.png", CV_LOAD_IMAGE_ANYCOLOR);
IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, );
IplImage *pSobelImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, );
//转成相应的灰度图像
cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
//进行Sobel边缘检测,注意xorder和yorder的不同,边缘检测的方向不同
//注意各种角度的边缘检测,不过核要自己设计
cvSobel(pGrayImage, pSobelImage, , , ); cvNamedWindow(ptrSrcImageWindowTitle, CV_WINDOW_AUTOSIZE);
cvNamedWindow(ptrGrayImageWindowTitle, CV_WINDOW_AUTOSIZE);
cvNamedWindow(ptrDesImageWindowTitle, CV_WINDOW_AUTOSIZE); cvShowImage(ptrSrcImageWindowTitle, pSrcImage);
cvShowImage(ptrGrayImageWindowTitle, pGrayImage);
cvShowImage(ptrDesImageWindowTitle, pSobelImage); cvWaitKey();
cvReleaseImage(&pSrcImage);
cvReleaseImage(&pGrayImage);
cvReleaseImage(&pSobelImage); cvDestroyWindow(ptrSrcImageWindowTitle);
cvDestroyWindow(ptrGrayImageWindowTitle);
cvDestroyWindow(ptrDesImageWindowTitle); }
附带知识:
普利维特算子(Prewitt operate):
除sobel边缘检测外 还有Prewitt算子, 它的卷积因子如下:

其他计算 和sobel差不多;
Prewitt算子利用像素点上下、左右邻点灰度差,在边缘处达到极值检测边缘。对噪声具有平滑作用,定位精度不够高。
罗伯茨交叉边缘检测(Roberts Cross operator)
卷积因子如下:

灰度公式为:

近似公式为:

具体计算如下:
G(x,y)=abs(f(x,y)-f(x+1,y+1))+abs(f(x,y+1)-f(x+1,y))
灰度方向 计算公式为:

Roberts算子采用对角线方向相邻两像素之差近似梯度幅值检测边缘。检测水平和垂直边缘的效果好于斜向边缘,定位精度高,对噪声敏感。

边缘检测之Sobel检测算子的更多相关文章
- opencl初探-sobel检测
sobel检测的C版本,neon和GPU的时间比较. Platform: LG G3, Adreno 330 ,img size 3264x2448 sobel: C code neon GPU 73 ...
- 【OpenCV】边缘检测:Sobel、拉普拉斯算子
推荐博文,博客.写得很好,给个赞. Reference Link : http://blog.csdn.net/xiaowei_cqu/article/details/7829481 一阶导数法:梯度 ...
- opencv —— Sobel 一阶导数算子、Scharr 滤波器 一阶导数用于边缘检测
sobel 算子的基本概念 sobel 算子是一个主要用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导,用于计算图像灰度函数的近似梯度. 其基础来自于一个事实,即在边缘部分,像素值出现“跳跃”或 ...
- OpenCV——边缘检测(sobel算子、Laplacian算子、scharr滤波器)
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...
- SUSAN检测算子
USAN区域(核同值区):和核像素的灰度相同会相信的模板像素的区域. 利用这个区域的尺寸.重心.二阶矩等可以帮助检测图像的边缘和角点.利用USAN的面积作为特征可以起到增强边缘和角点的效果. 该方法不 ...
- OpenCV图像处理篇之边缘检测算子
OpenCV图像处理篇之边缘检测算子 转载: http://xiahouzuoxin.github.io/notes/ 3种边缘检测算子 一阶导数的梯度算子 高斯拉普拉斯算子 Canny算子 Open ...
- Matlab中边缘提取方法简析
1.Matlab简述 Matlab是国际上最流行的科学与工程计算的软件工具,它起源于矩阵运算,已经发展成一种高度集成的计算机语言.有人称它为“第四代”计算机语言,它提供了强大的科学运算.灵活的程序设计 ...
- 在UnrealEngine中用Custom节点实现描边效果
在<Real Time Rendering, third edition>一书中,作者把描边算法分成了5种类型.1.基于观察角度与表面法线的轮廓渲染.缺点很明显.2.过程式几何轮廓渲染.即 ...
- 基于matlab的边缘提取方法的比较
1.Matlab简述 Matlab是国际上最流行的科学与工程计算的软件工具,它起源于矩阵运算,已经发展成一种高度集成的计算机语言.有人称它为“第四代”计算机语言,它提供了强大的科学运算.灵活的程序设计 ...
随机推荐
- android开发 不注意的异常
近期刚上班,做了一个应用,要上线.測试天天測试,天天有bug,个人总结了几个常常忽略的地方: 1:在 继承 BaseAdapter 的 @Override public int getCount() ...
- Java File类读取文件属性
package myjavademo;import java.io.*; publicclass MyJavaDemo { public static void main(String[] ...
- NLS_COMP和NLS_SORT参数
Oracle默认是采用binary进行排序,这对于例如中文的排序来说,是不恰当的.使用这两个参数可以指定排序的方法,比如拼音或是,要注意可能会引起性能问题.解决方法是使用NLSSORT函数来建立一个函 ...
- 【枚举+小技巧】【TOJ4115】【Find the number】
题目大意 找到一个最小的奇数 约数个数为n 结果mod10^9+7 根据 约数个数=(p1+1)*(p2+1)............ 将n 枚举分解成连乘式.(枚举个数,dfs) 比较大小 log ...
- 前端开发必备的Sublime 3插件
Sublime的大名已经无需我介绍了,首先先介绍如何启用插件安装功能: 打开Sublime 3,然后按 ctrl+` 或者在View → Show Console 在打开的窗口里黏贴这个网站上的代码( ...
- ubuntu 配置JDK环境变量
ubuntu 配置JDK环境变量 (2011-11-25 16:45:59) 转载▼ 标签: ubuntu jdk 环境变量 杂谈 分类: Linux_Ubuntu_CentOs 过程如下: 1. 先 ...
- c语言函数实现交换两个数的值
代码: #include <stdio.h> void swap(int x,int y) { int temp; temp = x; x = y; y = temp; printf(&q ...
- iOS在Xcode6中添加空模板
1.在Xcode6.0以下版本找到空模板(路径与下方相同). 2.将空模板拖入路径:Macintosh HD ▸ 应用程序 ▸ Xcode(版本号).app ▸ Contents ▸ Develo ...
- memcache 安装教程
memcached:官网http://memcached.org/ 说明:memcached本身没有Linux版本,网上的windows 版本都是个人开发的. memcached和memcache区别 ...
- mysql zk切换整个过程
<pre name="code" class="html">mysql master: test:/root/zk# cat zk.pl use Z ...