paper 82:边缘检测的各种微分算子比较(Sobel,Robert,Prewitt,Laplacian,Canny)

不同图像灰度不同,边界处一般会有明显的边缘,利用此特征可以分割图像。需要说明的是:边缘和物体间的边界并不等同,边缘指的是图像中像素的值有突变的地方,而物体间的边界指的是现实场景中的存在于物体之间的边界。有可能有边缘的地方并非边界,也有可能边界的地方并无边缘,因为现实世界中的物体是三维的,而图像只具有二维信息,从三维到二维的投影成像不可避免的会丢失一部分信息;另外,成像过程中的光照和噪声也是不可避免的重要因素。正是因为这些原因,基于边缘的图像分割仍然是当前图像研究中的世界级难题,目前研究者正在试图在边缘提取中加入高层的语义信息。

在实际的图像分割中,往往只用到一阶和二阶导数,虽然,原理上,可以用更高阶的导数,但是,因为噪声的影响,在纯粹二阶的导数操作中就会出现对噪声的敏感现象,三阶以上的导数信息往往失去了应用价值。二阶导数还可以说明灰度突变的类型。在有些情况下,如灰度变化均匀的图像,只利用一阶导数可能找不到边界,此时二阶导数就能提供很有用的信息。二阶导数对噪声也比较敏感,解决的方法是先对图像进行平滑滤波,消除部分噪声,再进行边缘检测。不过,利用二阶导数信息的算法是基于过零检测的,因此得到的边缘点数比较少,有利于后继的处理和识别工作。

各种算子的存在就是对这种导数分割原理进行的实例化计算,是为了在计算过程中直接使用的一种计算单位。

Roberts算子:边缘定位准,但是对噪声敏感。适用于边缘明显且噪声较少的图像分割。Roberts边缘检测算子是一种利用局部差分算子寻找边缘的算子,Robert算子图像处理后结果边缘不是很平滑。经分析,由于Robert算子通常会在图像边缘附近的区域内产生较宽的响应,故采用上述算子检测的边缘图像常需做细化处理,边缘定位的精度不是很高。

Prewitt算子:对噪声有抑制作用,抑制噪声的原理是通过像素平均,但是像素平均相当于对图像的低通滤波,所以Prewitt算子对边缘的定位不如Roberts算子。

Sobel算子:Sobel算子和Prewitt算子都是加权平均,但是Sobel算子认为,邻域的像素对当前像素产生的影响不是等价的,所以距离不同的像素具有不同的权值,对算子结果产生的影响也不同。一般来说,距离越远,产生的影响越小。

Isotropic Sobel算子:加权平均算子,权值反比于邻点与中心点的距离,当沿不同方向检测边缘时梯度幅度一致,就是通常所说的各向同性。

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

上面的算子是利用一阶导数的信息,属于梯度算子范畴。

Laplacian算子:这是二阶微分算子。其具有各向同性,即与坐标轴方向无关,坐标轴旋转后梯度结果不变。但是,其对噪声比较敏感,所以,图像一般先经过平滑处理,因为平滑处理也是用模板进行的,所以,通常的分割算法都是把Laplacian算子和平滑算子结合起来生成一个新的模板。

Laplacian算子一般不以其原始形式用于边缘检测,因为其作为一个二阶导数,Laplacian算子对噪声具有无法接受的敏感性;同时其幅值产生算边缘,这是复杂的分割不希望有的结果;最后Laplacian算子不能检测边缘的方向;所以Laplacian在分割中所起的作用包括:(1)利用它的零交叉性质进行边缘定位;(2)确定一个像素是在一条边缘暗的一面还是亮的一面;一般使用的是高斯型拉普拉斯算子(Laplacian of a Gaussian,LoG),由于二阶导数是线性运算,利用LoG卷积一幅图像与首先使用高斯型平滑函数卷积改图像,然后计算所得结果的拉普拉斯是一样的。所以在LoG公式中使用高斯函数的目的就是对图像进行平滑处理,使用Laplacian算子的目的是提供一幅用零交叉确定边缘位置的图像;图像的平滑处理减少了噪声的影响并且它的主要作用还是抵消由Laplacian算子的二阶导数引起的逐渐增加的噪声影响。

微分算子在图像处理中扮演重要的角色,其算法实现简单,而且边缘检测的效果又较好,因此这些基本的微分算子是学习图像处理过程中的必备方法,下面着重讨论几种常见的微分算子。

1.Sobel

其主要用于边缘检测,在技术上它是以离散型的差分算子,用来运算图像亮度函数的梯度的近似值,缺点是Sobel算子并没有将图像的主题与背景严格地区分开来,换言之就是Sobel算子并没有基于图像灰度进行处理,由于Sobel算子并没有严格地模拟人的视觉生理特征,所以提取的图像轮廓有时并不能令人满意,算法具体实现很简单,就是3*3的两个不同方向上的模板运算,这里不再写出。

2.Robert算子

根据任一相互垂直方向上的差分都用来估计梯度,Robert算子采用对角方向相邻像素之差

3.Prewitt算子

该算子与Sobel算子类似,只是权值有所变化,但两者实现起来功能还是有差距的,据经验得知Sobel要比Prewitt更能准确检测图像边缘。

4.Laplacian算子

拉普拉斯算子是一种二阶微分算子,若只考虑边缘点的位置而不考虑周围的灰度差时可用该算子进行检测。对于阶跃状边缘,其二阶导数在边缘点出现零交叉,并且边缘点两旁的像素的二阶导数异号。

5.Canny算子

该算子功能比前面几种都要好,但是它实现起来较为麻烦,Canny算子是一个具有滤波,增强,检测的多阶段的优化算子,在进行处理前,Canny算子先利用高斯平滑滤波器来平滑图像以除去噪声,Canny分割算法采用一阶偏导的有限差分来计算梯度幅值和方向,在处理过程中,Canny算子还将经过一个非极大值抑制的过程,最后Canny算子还采用两个阈值来连接边缘。

下面算法是基于的算法不可能直接运行,只是把Canny的具体实现步骤写了出来,若需用还要自己写。

该算子具体实现方法:

// anny.cpp: implementation of the Canny class.
//
//////////////////////////////////////////////////////////////////////

#include "anny.h"
#include "math.h"
//#include "algorithms.h"
//#include "algorithm.h"
#include "stdlib.h"
//#include "maths.h"
//using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Canny::Canny(int PicHeight,int PicWidth,double ** PicData,double PicSigma,double PicRatioLow,double PicRatioHigh)
{
 iHeight=PicHeight;
 iWidth=PicWidth;
 iData=PicData;
 sigma=PicSigma;
 dRatioLow=PicRatioLow;
 dRatioHigh=PicRatioHigh;
}

Canny::~Canny()
{

}

void Canny::CannyArith(int **iEdgePoint)
{
 int i;
 int **iGradX ;                       // 指向x方向导数的指针
    int **iGradY ;                         // 指向y方向导数的指针
    int **iExtent ;                      // 梯度的幅度
 iGradX=new int *[iHeight];
 for(i=0;i
  iGradX[i]=new int[iWidth];
 iGradY=new int *[iHeight];
 for(i=0;i
  iGradY[i]=new int[iWidth];
 iExtent=new int *[iHeight];
 for(i=0;i
  iExtent[i]=new int[iWidth];

 // 对原图象进行滤波
         GaussionSmooth();
// 计算X,Y方向上的方向导数
    DirGrad(iGradX,iGradY);
    // 计算梯度的幅度
    GradExtent(iGradX,iGradY,iExtent);
    // 应用non-maximum 抑制
   NonMaxSuppress(iExtent,iGradX,iGradY,iEdgePoint);
 // 应用Hysteresis,找到所有的边界
    Hysteresis(iExtent,iEdgePoint);
 // 释放内存
 for(i=0;i
        delete  []*(iGradX+i);
    delete   iGradX;
 for(i=0;i
        delete  []*(iGradY+i);
    delete   iGradY;
 for(i=0;i
        delete  []*(iExtent+i);
    delete   iExtent;

}

void Canny::GaussionSmooth()
{
 int i,j,k;                             //循环变量
 int iWindowSize;                       //记录模板大小的变量
 int iHalfLen;                          //模板大小的一半
 double *pdKernel;                         //模板各点的权值
 double dDotMul;                        //模板与对应像素点的卷积和
 double dWeightSum;                     //模板的权值累加和
 double **dTemp;                         //记录图像数据的中间变量
 //开辟空间
 dTemp=new double *[iHeight];
 for(i=0;i
  dTemp[i]=new double[iWidth];
 //获得模板长度和模板的各个权值
 MakeGauss(&pdKernel,&iWindowSize);
 //得到模板的一半长度
 iHalfLen=iWindowSize/2;
 //对图像对水方向根据模板进行平滑
 for(i=0;i
 {
  for(j=0;j
  {
   dDotMul=0;
   dWeightSum=0;
   for(k=(-iHalfLen);k<=iHalfLen;k++)
   {
    if((k+j>=0)&&(k+j
    {
     dDotMul+=iData[i][j+k]*pdKernel[k+iHalfLen];
     dWeightSum+=pdKernel[k+iHalfLen];

    }
   }
   dTemp[i][j]=dDotMul/dWeightSum;
  }
 }
 //对图像垂直方向上根据模板的转置进行平滑(注意图像数据是在水平平滑之后进行的)
 for(i=0;i
 {
  for(j=0;j
  {
   dDotMul=0;
   dWeightSum=0;
   for(k=(-iHalfLen);k<=iHalfLen;k++)
   {
    if((k+j>=0)&&(k+j
    {
     dDotMul+=dTemp[j+k][i]*pdKernel[k+iHalfLen];
     dWeightSum+=pdKernel[k+iHalfLen];

    }
   }
   iData[j][i]=dDotMul/dWeightSum;
  }
 }
 //空间释放
    delete []pdKernel;
 pdKernel=NULL;
 for(i=0;i
        delete  []*(dTemp+i);
    delete   dTemp; 

}

void Canny::MakeGauss(double **pdKernel,int *iWindowSize)
{
 int i;                             //循环变量
 int nCenter;                       //确定高斯模板的一半长度
 double dDistance;                  //一维高斯模板各点离中心点的距离
 double PI=3.1415926;               //圆周率
 double dValue;                     //中间变量,记录高斯模板各点的权值(未经归一化)
 double dSum=0;                     //中间变量,记录高斯模板各点权值的总和
 *iWindowSize=int(1+2*int(3*sigma+0.5));    //确定一维高斯模板长度,根据概率论的知识,选取[-3*sigma, 3*sigma]以内的数据。
 nCenter=(*iWindowSize)/2;          //得到一半长度
 *pdKernel=new double[*iWindowSize];//开辟记录各点权值的空间

 //利用高斯分布函数(正太分布)确定各点的权值,主要是根据高斯分布离中心点的距离越远,所取的值就越小,这与图像有些
 //相似,离中心点越远,对中心点的影响就越小。
 for(i=0;i<(*iWindowSize);i++)
 {
  dDistance=double(i-nCenter);
  //高斯分布函数求值
  dValue=exp((-1/2)*dDistance*dDistance/(sigma*sigma))/(sqrt(2*PI)*sigma);
  (*pdKernel)[i]=dValue;
  dSum+=dValue;

 }
 //归一化(因为要不改变原图像的灰度区域,就必须保证各权值之和为1
 for(i=0;i<(*iWindowSize);i++)
 {
  (*pdKernel)[i] /= dSum;
 }
}

void Canny::DirGrad(int **iGradX,int **iGradY)
{
 int i,j,temp1,temp2;
 //水平方向的方向导数(下面都是用min和max对边界值做了相应的处理)
 for(i=0;i
 {
  for(j=0;j
  {

   if(iWidth-1
    temp1=iWidth-1;
   else
    temp1=j+1;
   if(0
    temp2=j-1;
   else
    temp2=0;

   iGradX[i][j]=int(iData[i][temp1]-iData[i][temp2]);
  }
 }
 //垂直方向的方向导数
 for(i=0;i
 {
  for(j=0;j
  {
   if(iHeight-1
    temp1=iHeight-1;
   else
    temp1=j+1;
   if(0
    temp2=j-1;
   else
    temp2=0;
   iGradY[j][i]=int(iData[temp1][i]-iData[temp2][i]);
  }
 }
}

void Canny::GradExtent(int **iGradX,int **iGradY,int **iExtent)
{
 int i,j;
 double iTemp1,iTemp2;
 for(i=0;i
 {
  for(j=0;j
  {
   iTemp1=iGradX[i][j]*iGradX[i][j];
   iTemp2=iGradY[i][j]*iGradY[i][j];
   iExtent[i][j]=int(sqrt(iTemp1+iTemp2)+0.5);
  }
 }
}

void Canny::NonMaxSuppress(int **iExtent,int **iGradX,int **iGradY,int **dUnchRst)
{
 int i,j;
 int gx,gy;                     //记录像素点X,Y 方向的方向导数值
 int g1,g2,g3,g4;               //各个领域的梯度值
 double weight;                    //比重
 double dTemp1,dTemp2,dTemp;       //中间变量
 //处理边缘值(边缘点不可能是边界点
  for(i=0;i
 {
  dUnchRst[i][0]=0;
  dUnchRst[i][iWidth-1]=0;
 }
 for(j=0;j
 {
  dUnchRst[0][j]=0;
  dUnchRst[iHeight-1][j]=0;
 }
 //标记有可能是边界点的像素点
 for(i=1;i
 {
  for(j=1;j
  {
   //梯度值是0的像素点不可能是边界点
   if(iExtent[i][j]==0)
    dUnchRst[i][j]=0;
   else
   {
    dTemp=iExtent[i][j];
    gx=iGradX[i][j];
    gy=iGradY[i][j];
    //下面都是判断当前像素点的梯度值和其领域像素点的梯度值,如大于就有可能是边界点,如小于就不可能是边界点
    if(abs(gy)>abs(gx))
    {
                       weight=double(abs(gx)/abs(gy));
        g2=iExtent[i-1][j];
        g4=iExtent[i+1][j];
        if(gx*gy>0)
        {
         g1=iExtent[i-1][j-1];
         g3=iExtent[i+1][j+1];
        }
        else
        {
         g1=iExtent[i-1][j+1];
         g3=iExtent[i+1][j-1];
        }
    }
    else
    {
     weight=double(abs(gy)/abs(gx));
     g2=iExtent[i][j+1];
     g4=iExtent[i][j-1];
     if(gx*gy>0)
     {
      g1=iExtent[i+1][j+1];
      g3=iExtent[i-1][j-1];
     }
     else
     {
      g1=iExtent[i-1][j+1];
      g3=iExtent[i+1][j-1];
     }
    }
    dTemp1=weight*g1+(1-weight)*g2;
    dTemp2=weight*g3+(1-weight)*g4;
    //当大于的时候就有可能是边界点
    if(dTemp>=dTemp1&&dTemp>=dTemp2)
    {
     dUnchRst[i][j] = 128 ;
    }
    else
    {

     dUnchRst[i][j]=0 ;
    }
   }

  }
 }
}

void Canny::Hysteresis(int **iExtent,int **iEdgePoint)
{
 int i,j;
 int iThreHigh;
 int iThreLow;
 SetThreshold(iExtent,&iThreHigh,&iThreLow,iEdgePoint);
 for(i=0;i
 {
  for(j=0;j
  {
   if((iEdgePoint[i][j]==128)&&(iExtent[i][j]>=iThreHigh))
   {
    iEdgePoint[i][j]=255;
    TraceEdge(i,j,iThreLow,iEdgePoint,iExtent);

   }

  }
 }
 // 那些还没有被设置为边界点的象素已经不可能成为边界点
 for(i=0;i
 {
  for(j=0;j
  {

   if(iEdgePoint[i][j]!=255)
   {
    // 设置为非边界点
    iEdgePoint[i][j] = 0 ;
   }
  }
  }

}

void Canny::SetThreshold(int **iExtent,int *iThreHigh,int *iThreLow,int **iEdgePoint)
{

 int i,j,k;
 int GradHist[1024];                     //统计梯度直方图的数据,梯度最大值不可能超过1024
 int iEdgeNum;                           //边界点的数量
 int iGradMax=0;                         //边界点的梯度最大值
 int iHighCount;                         //根据iRatioHigh小于高阈值像素的个数
 //初始化
 for(i=0;i<1024;i++)
  GradHist[i]=0;
 //梯度直方图统计
 for(i=0;i
 {
  for(j=0;j
  {
   if(iEdgePoint[i][j]==128)
   {
    GradHist[iExtent[i][j]]++;
   }
  }
 }
 iEdgeNum=0;
 //找出最大梯度和统计边界点的个数
 for(i=0;i<1024;i++)
 {
  if(GradHist[i]!=0)
   iGradMax=i;
  iEdgeNum+=GradHist[i];
 }
 //获得小于高阈值的个数
 iHighCount=int(iEdgeNum*dRatioHigh+0.5);
 k=1;
 iEdgeNum=GradHist[1];
 //求出高阈值
 while((k<=(iGradMax-1))&&(iEdgeNum
 {
  k++;
  iEdgeNum+=GradHist[k];
 }
 *iThreHigh=k;
 //根据高阈值和比例关系求得低阈值
 *iThreLow=int((*iThreHigh)*dRatioLow+0.5);

}

void Canny::TraceEdge(int y,int x,int iThreLow,int **iEdgePoint,int **iExtent)
{
 // 对8邻域象素进行查询
 int xNb[8] = {1, 1, 0,-1,-1,-1, 0, 1} ;
 int yNb[8] = {0, 1, 1, 1,0 ,-1,-1,-1} ;
 int yy ;
 int xx ;
 int k  ;
 for(k=0;k<8;k++)
 {
  yy=y+yNb[k] ;
  xx=x+xNb[k] ;
 // 如果该象素为可能的边界点,又没有处理过, 并且梯度大于阈值
  if(iEdgePoint[yy][xx]==128&&iExtent[yy][xx]>=iThreLow)

{
 // 把该点设置成为边界点
  iEdgePoint[yy][xx]=255 ;
 // 以该点为中心进行跟踪
      //TraceEdge(yy,xx,iThreLow,iEdgePoint,iExtent);

  }
 }
}

  

时间: 2024-10-20 19:27:25

paper 82:边缘检测的各种微分算子比较(Sobel,Robert,Prewitt,Laplacian,Canny)的相关文章

Opencv图像识别从零到精通(19)----Robert,prewitt,Sobel边缘检测

图像的边缘检测,是根据灰度的突变或者说不连续来检测,对于其中的算子有一阶导数和二价导数,这里先说基础的三种方法---Robert,prewitt,Sobel边缘检测.  一.梯度 首先介绍下梯度,梯度并非是一个数值,梯度严格意义上是一个向量,这个向量指向当前位置变化最快的方向,可以这么理解,当你站在一个山上,你有360°的方向可以选择,哪个方向下降速度最快(最陡峭),便是梯度方向,梯度的长度,表示为向量的长度,表示最大的变化速率. 梯度的数学表达: 在二维中只取前两项,也就是由x方向的偏微分和y

OpenCV——边缘检测(sobel算子、Laplacian算子、scharr滤波器)

1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 4 using namespace cv; 5 using namespace std; 6 7 8 int main(int argc, char** argv) 9 { 10 Mat src = imread("test.jpg"); 11 Mat dst, gray,grad_x, gray_y,abs_grad_x,abs_grad_y; 12

【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑.高斯平滑.不同算子的图像锐化知识.希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生. [数字图像处理]一.MFC详解显示BMP格式图片 [数字图像处理]二.MFC单文档分割窗口显示图片 [数字图像处理]三.MFC实现图像灰度.采样和量化功能详解 [数字图像处理]四.MFC对话框绘制灰度直方图 [数字图像

【火炉炼AI】机器学习046-图像边缘的检测方法

[火炉炼AI]机器学习046-图像边缘的检测方法 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 图像中各种形状的检测时计算机视觉领域中非常常见的技术之一,特别是图像中直线的检测,圆的检测,图像边缘的检测等,下面我们来研究一下如何快速检测图像边缘. 边缘是不同区域的分界线,是周围(局部)像素有显著变化的像素的集合,有幅值与方向两个属性.这个不是绝对的定义,主要记住边缘是局部特征以及周围

【opencv入门之九】Opencv边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器

参考网站: http://blog.csdn.net/poem_qianmo/article/details/25560901 1.边缘检测步骤 1)滤波:边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感.( 通常用高斯滤波 ) 2)增强:增强边缘的基础是确定图像各点领域强度的变化值.增强算法可以将图像灰度点领域强度值有显著变化的点凸显出来.( 可以通过计算梯度幅值来确定 ) 3)检测:经过增强的图像,往往领域中有很多点的梯度值比较大,而特定的应用中,这些点并不是我们要找

学习 opencv---(11)OpenC 边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器

本篇文章中,我们将一起学习OpenCV中边缘检测的各种算子和滤波器--Canny算子,Sobel算子,Laplace算子以及Scharr滤波器.文章中包含了五个浅墨为大家准备的详细注释的博文配套源代码.在介绍四块知识点的时候分别一个,以及最后的综合示例中的一个.文章末尾提供配套源代码的下载. **** 给大家分享一个OpenCv中写代码是节约时间的小常识.其实OpenCv中,不用nameWindow,直接imshow就可以显示出窗口.大家看下文的示例代码就可以发现,浅墨在写代码的时候并没有用na

【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 知乎:http://www.zhihu.com/people/mao-xing-yun 邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本: 2.4.9 本篇文章中,我们将一起学习OpenCV中

OpenCV使用Sobel滤波器实现图像边缘检测

纯粹阅读,请移步OpenCV使用Sobel滤波器实现图像边缘检测 效果图 源码 KqwOpenCVFeaturesDemo Sobel滤波器也叫Sobel算子,与Canny边缘检测一样,需要计算像素的灰度梯度,只不过是换用另一种方式. 使用Sobel算子计算边缘的步骤 将图像转为灰度图像 // 原图置灰 Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY); 计算水平方向灰度梯度的绝对值 Imgproc.Sobel(grayMat, gra

图像处理常用边缘检测算子总结

图像处理常用边缘检测算子总结 转 不同图像灰度不同,边界处一般会有明显的边缘,利用此特征可以分割图像.需要说明的是:边缘和物体间的边界并不等同, 边缘指的是图像中像素的值有突变的地方,而物体间的边界指的是现实场景中的存在于物体之间的边界.有可能有边缘的地方并非边界,也有可能边界的地方并无边 缘,因为现实世界中的物体是三维的,而图像只具有二维信息,从三维到二维的投影成像不可避免的会丢失一部分信息:另外,成像过程中的光照和噪声也是不可避 免的重要因素.正是因为这些原因,基于边缘的图像分割仍然是当前图