Sobel算子 百科内容来自于: 百度百科

由来

对于已经写入数字图像处理及机器视觉教科书多年的Sobel算子,谁也没曾追问和关心过它的发明背景和历史。最近,给学生上“光电图像处理”课,想介绍一下该算子的来历,查了很多文献,就是找不到原始文献。Google学术里搜索,信息很多,却不一致。有标注为期刊论文的,也有标注出版物析出的,出版时间也不一致(冈萨雷斯《Digital Image Processing》教材标注的时间为1970年)。
Irwin Sobel
这个看似简单,但领域内科研、开发人员沿用了几十年的边缘检测算子,偶然发现一个帖子,该算子的提出者Irwin Sobel,多年后详细谈到了算子的由来和定义。
原来,这个著名的Sobel边缘算子,当年作者并没有公开发表过论文,仅仅是在一次博士生课题讨论会(1968)上提出("A 3x3 Isotropic Gradient Operator for Image Processing"),后在1973年出版的一本专著("Pattern Classification and Scene Analysis")的脚注里作为注释出现和公开的。
图1 x和y两个方向的sobel算子模板
图2 灰度图像sobel算子处理效果图

核心公式

该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经纵向向及横向边缘检测的图像,其公式如下:
图像的每一个像素的横向及纵向梯度近似值可用以下的公式结合,来计算梯度的大小。
然后可用以下公式计算梯度方向。
在以上例子中,如果以上的角度Θ等于零,即代表图像该处拥有纵向边缘,左方较右方暗。

算子描述

在边缘检测中,常用的一种模板是Sobel 算子。Sobel 算子有两个,一个是检测水平边缘的 ;另一个是检测垂直边缘的 。与Prewitt算子相比,Sobel算子对于象素的位置的影响做了加权,可以降低边缘模糊程度,因此效果更好。
Sobel算子另一种形式是各向同性Sobel(Isotropic Sobel)算子,也有两个,一个是检测水平边缘的 ,另一个是检测垂直边缘的 。各向同性Sobel算子和普通Sobel算子相比,它的位置加权系数更为准确,在检测不同方向的边沿时梯度的幅度一致。将Sobel算子矩阵中的所有2改为根号2,就能得到各向同性Sobel的矩阵。
由于Sobel算子是滤波算子的形式,用于提取边缘,可以利用快速卷积函数, 简单有效,因此应用广泛。美中不足的是,Sobel算子并没有将图像的主体与背景严格地区分开来,换言之就是Sobel算子没有基于图像灰度进行处理,由于Sobel算子没有严格地模拟人的视觉生理特征,所以提取的图像轮廓有时并不能令人满意。 在观测一幅图像的时候,我们往往首先注意的是图像与背景不同的部分,正是这个部分将主体突出显示,基于该理论,我们给出了下面阈值化轮廓提取算法,该算法已在数学上证明当像素点满足正态分布时所求解是最优的。

.NET代码

unsignedcharComputeSobel(unsignedcharul,//upperleftunsignedcharum,//uppermiddleunsignedcharur,//upperrightunsignedcharml,//middleleftunsignedcharmm,//middle(unused)unsignedcharmr,//middlerightunsignedcharll,//lowerleftunsignedcharlm,//lowermiddleunsignedcharlr,//lowerrightfloatfScale){shortHorz=ur+2*mr+lr-ul-2*ml-ll;shortVert=ul+2*um+ur-ll-2*lm-lr;shortSum=(short)(fScale*(abs((int)Horz)+abs((int)Vert)));
if(Sum<0){return0;}elseif(Sum>0xff){return0xff;}
return(unsignedchar)Sum;}

for(Times=0;Times<128&&iThreshold!=iNewThreshold;Times++)
{
iThreshold=iNewThreshold;
lP1=0;
lP2=0;
lS1=0;
lS2=0;
for(i=iMinGray;i<iThreshold;i++)
{
lP1+=Histogram*i;
lS1+=Histogram;
}
iMean1Gray=lP1/lS1;
for(i=iThreshold;i<iMaxGray;i++)
{
lP2+=Histogram*i;
lS2+=Histogram;
}
iMean2Gray=lP2/lS2;
iNewThreshold=(iMean1Gray+iMean2Gray)/2;
}
//补充Sobel算子的矩阵表达式:
Sobel1=[-1-2-1;
000;
121];//检测垂直边沿的Sobel算子
Sobel2=[10-1;
20-2;
10-1];//检测水平边沿的Sobel算子

C代码

void MySobel(IplImage* gray, IplImage* gradient)
{
/* Sobel template
a00 a01 a02
a10 a11 a12
a20 a21 a22
*/
unsigned char a00, a01, a02;
unsigned char a10, a11, a12;
unsigned char a20, a21, a22;
CvScalar color ;
for (int i=1; i<gray->height-1; ++i)
{
for (int j=1; j<gray->width-1; ++j)
{
a00 = cvGet2D(gray, i-1, j-1).val[0];
a01 = cvGet2D(gray, i-1, j).val[0];
a02 = cvGet2D(gray, i-1, j+1).val[0];
a10 = cvGet2D(gray, i, j-1).val[0];
a11 = cvGet2D(gray, i, j).val[0];
a12 = cvGet2D(gray, i, j+1).val[0];
a20 = cvGet2D(gray, i+1, j-1).val[0];
a21 = cvGet2D(gray, i+1, j).val[0];
a22 = cvGet2D(gray, i+1, j+1).val[0];
// x方向上的近似导数
double ux = a20 * (1) + a21 * (2) + a22 * (1)
+ (a00 * (-1) + a01 * (-2) + a02 * (-1));
// y方向上的近似导数
double uy = a02 * (1) + a12 * (2) + a22 * (1)
+ a00 * (-1) + a10 * (-2) + a20 * (-1);
color.val[0] = sqrt(ux*ux + uy*uy);
cvSet2D(gradient, i, j, color);
}
}
}
//注释:该程序需要在安装Opencv软件下运行。
Matlab
ps=imread('D:\14.jpg'); %读取图像
subplot(1,3,1)
imshow(ps);
title('原图像');
ps=rgb2gray(ps);
[m,n]=size(ps); %用Sobel微分算子进行边缘检测
pa = edge(ps,'sobel');
subplot(1,3,2);
imshow(pa);
title('Sobel边缘检测得到的图像');
$firstVoiceSent
- 来自原声例句
小调查
请问您想要如何调整此模块?

感谢您的反馈,我们会尽快进行适当修改!
进来说说原因吧 确定
小调查
请问您想要如何调整此模块?

感谢您的反馈,我们会尽快进行适当修改!
进来说说原因吧 确定