边缘提取,或者说边缘检测,可以有很多方法,可以使用各种算子,其实就是说的模板操作,这些算子得到的边缘具有一定的厚度,还需要进行下一步的处理,CANNY算子是比较近的,性能比较好,而且提出了边缘检测的标准;可以使用形态学操作,得到的边缘是单个像素的,而且速度比较快。这个学习过程中,首先介绍一些边缘检测的算子,然后是基于形态学的检测方法,并最比较。
拉普拉斯算子,是基于二次微分,检测的精度很高,但是对于噪声很敏感,s使用的范围就很有限。
现在使用拉普拉斯算子都是把它和高斯滤波结合在一起使用,来降低噪声的影响。这种方法到的精度很高,但是也有很多的缺点。首先得到的图像是一幅具有零交叉点的图片,需要通过阈值处理才能得到边缘,而是图像边缘有空心粉效应,还有就是对噪声的敏感。
推荐一些文章:
一位老师的博客,
将算子和数学方法结合在一起,讲的很好,极力推荐。
一些代码: 写的挺简单的,但是不够规范
一些资料:
下面是我的代码:
/********************************************************************************
LOG边缘检测
鉴于拉普拉斯函数对噪声的敏感性,使用高斯函数对图片进行滤波,然后使用拉普拉斯模板处理,
实际使用的时候是使用复合模板进行处理(墨西哥草帽),得到一幅零交叉确定边缘的图片
使用LOG模板以后可以使用阈值处理,负值为黑色,正值为白色,
LOG的优点得到的边缘精度很高,但是会产生空心粉效应,而且对噪声很敏感
**************************
×××得到的一幅零交叉确定边缘的图片,通过求取零交叉点来确定边缘
********************************************************************************/
BOOL ImgEdge_LOG(BITMAPINFO* pbmpinfo,BYTE* pbmpdata)
{
int template_box[25]={
0, 0, -1, 0, 0,
0, -1, -2, -1, 0,
-1, -2, 16, -2, -1,
0, -1, -2, -1, 0,
0, 0, -1, 0, 0
};
LONG imagewidth=pbmpinfo->bmiHeader.biWidth;
LONG imageheigth=pbmpinfo->bmiHeader.biHeight;
LONG i=0,j=0,k=0,heigth=0,width=0;
//data is not null
if (pbmpdata == NULL)
{
return FALSE;
}
//color must be gray
if (pbmpinfo->bmiHeader.biBitCount != 8)
{
AfxMessageBox("只对灰度图像进行操作!");
return FALSE;
}
//image size
LONG Linebyte =( pbmpinfo->bmiHeader.biBitCount * imagewidth +31)/32*4;
LONG ImageSize=Linebyte * imageheigth;
//分配空间
BYTE *pNewbmpdata=(BYTE*)malloc(ImageSize);
//copy data
if (pNewbmpdata == NULL)
{
return FALSE;
}
memcpy(pNewbmpdata,pbmpdata,ImageSize);
BYTE *psrc=NULL;
BYTE *pdest=NULL;
LONG tempnum=0;
//计算区域是:begin~image-begin-1 1~image-2
for (heigth = 2 ; heigth < imageheigth - 2 ;heigth++ )
{
for ( width = 2 ; width < imagewidth - 2 ; width++)
{
psrc = pbmpdata+(ImageSize-Linebyte-
heigth*Linebyte)+width;
pdest = pNewbmpdata+(ImageSize-Linebyte-
heigth*Linebyte)+width;
j=0;
tempnum=0;
for ( i = - 2 ; i < 3 ;i++)
{
for (k = - 2 ; k < 3 ;k++)
{
tempnum += (LONG)(*(psrc + i * Linebyte + k)) * template_box[j++];
}
}
if (tempnum>255)
{
tempnum=255;
}
if (tempnum<0)
{
tempnum=0;
}
*pdest=(unsigned char)tempnum;
}
}
memcpy(pbmpdata,pNewbmpdata,ImageSize);
free(pNewbmpdata);
return TRUE;
}
文章评论(0条评论)
登录后参与讨论