原创 (原创)图像处理学习系列3:边缘t检测之拉普拉斯算子

2009-3-13 20:48 6090 4 4 分类: 软件与OS

    边缘提取,或者说边缘检测,可以有很多方法,可以使用各种算子,其实就是说的模板操作,这些算子得到的边缘具有一定的厚度,还需要进行下一步的处理,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条评论)

登录后参与讨论
相关推荐阅读
zhangshaobing517_935512703 2011-03-21 01:28
KC24RT-300调试笔记
项目中需要使用LED驱动器,主要是为了让一串LED发出的光照一致,所以在试验中采用LED串联的方式比较好点,LED并联容易导致LED发光的 不均匀以及寿命减少。我在项目中采用金升阳公司的KC24RT-...
zhangshaobing517_935512703 2010-11-19 14:53
线程中CreateEvent和SetEvent及WaitForSingleObj
首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面.CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象.EVENT有两种状态:发信...
zhangshaobing517_935512703 2010-11-15 13:29
VS2008 BEGIN
Visual Studio 2008环境与VC6.0的环境存在着比较大的区别,下面就一些小小的区别在这里做一些探讨,欢迎指教!1、如果是调试控制台程序,很多时候点击“启动调试”后是一闪而过,此时可有两...
zhangshaobing517_935512703 2010-11-01 20:38
使用MFC的数组类
 MFC的数组类支持的数组类似于C++中的常规数组,可以存放任何数据类型。C++的常规数组在使用前必须将其定义成能够容纳所有可能需要的元素,而MFC数组类创建的对象可以根据需要动态地增大或减小,数组的...
zhangshaobing517_935512703 2010-09-07 13:14
循环
 循环设计的注意的事情:(1)双重循环的跳出问题,break只挑出所在的循环,如果使用双层FOR循环,单个BREAK就不可能跳出所有的双层(2)在迭代的时候,注意起始和终止的条件,尤其是终止问题(3)...
zhangshaobing517_935512703 2010-09-02 01:09
图像处理改进
1.特征点提取的算法  标志点的提取算法对结果的影响虽然没有经过试验或者计算的推算,每1个pix的偏差对结果的影响有多大,但是不可避免的,要想获得高精度的  测量结果,高精度的提取对结果的影响还是很大...
我要评论
0
4
1
2
3
4
5
6
7
8
9
0
关闭 热点推荐上一条 /3 下一条