电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

(原创)图像处理学习系列3:边缘检测之一KIRSCH算子

[
   KIRSCH检测算子,推荐一篇文章](http://hi.baidu.com/liujianz/blog/item/1588c177ea73c21eb051b909.html " KIRSCH检测算子,推荐一篇文章"),该算子具有8个方向的模板,具有很好的方向性(俺还不理解这有啥好处),有很好的精度和抗噪性能,似乎在医学上用的挺多。不说了
一些文章;.
KIRSCH边缘检测算子快速算法.PDFPDF
一种改进的Kirsch边缘检测方法.pdfpdf
代码有2个,
基于快速边缘检测算法的:
/************************************************************************************
快速Kirsch算子:
能检测边缘方向,它使用了8个模板来确定梯度幅度值和梯度的方向
q=8max{r}
r0=0.625(p0+p1+p2)-0.375(p3+p4+p5+p6=p7)
r1=r0+p7-p2
r2=r1+p6-p1;
r3=r2+p5-p0;
r4=r3+p4-p7;
r5=r4+p3-p6;
r6=r5+p2-p5;
r7=r6+p1-p4;
*************************************************************************************/
//******************************
BOOL ImgEdge_FKC(BITMAPINFO* pbmpinfo,BYTE* pbmpdata)
{
    LONG imagewidth=(int)pbmpinfo->bmiHeader.biWidth;
    LONG imageheigth=(int)pbmpinfo->bmiHeader.biHeight;
    //image size
    LONG  Linebyte =( pbmpinfo->bmiHeader.biBitCount * imagewidth +31)/32*4;
    LONG  ImageSize=Linebyte * imageheigth;
    //data is not null
    if (pbmpdata == NULL)
    {
        return FALSE;
    }
    //color must be gray
    if (pbmpinfo->bmiHeader.biBitCount != 8)
    {
        AfxMessageBox("只对灰度图像进行操作!");
        return FALSE;
    }
        //copy
    BYTE *pNewbmpdata=(BYTE*)malloc(ImageSize);
    if (pNewbmpdata == NULL)
    {
        return FALSE;
    }
    memcpy(pNewbmpdata,pbmpdata,ImageSize);
    //memset(pNewbmpdata,255,ImageSize);
        //注意数组不要越界,不对右边和下边的数据进行处理
    LONG width=0,heigth=0;
    BYTE *psrc=NULL;
    BYTE *pdest=NULL;   
       
    int   temp_array[8]={0};
    float temp_result[8]={0};
    int result=0;
    for (heigth = 1; heigth < imageheigth - 1 ; heigth++)
    {
        for (width=1; width < imagewidth- 1; width++)
        {
            psrc  =  pbmpdata + ImageSize- Linebyte*heigth - Linebyte + width;
            pdest =  pNewbmpdata+ImageSize- Linebyte*heigth - Linebyte + width;
            //这里没有使用模板来做,减少寻址的次数
                        temp_array[0]= *(psrc-Linebyte-1);
            temp_array[1]= *(psrc-Linebyte);
            temp_array[2]= *(psrc-Linebyte+1);
            temp_array[3]= *(psrc+1);
                temp_array[4]= *(psrc+Linebyte+1);
            temp_array[5]= *(psrc+Linebyte);
            temp_array[6]= *(psrc+Linebyte-1);
            temp_array[7]= *(psrc-1);
            temp_result[0]=(float) ( (0.625*(temp_array[0]+temp_array[1]+temp_array[2]) - \
                 0.375 * (temp_array[3]+temp_array[4]+temp_array[5]+temp_array[6]+temp_array[7])));
            temp_result[1]=temp_result[0] + temp_array[7] - temp_array[2];
            temp_result[2]=temp_result[1] + temp_array[6] - temp_array[1];
            temp_result[3]=temp_result[2] + temp_array[5] - temp_array[0];
            temp_result[4]=temp_result[3] + temp_array[4] - temp_array[7];
            temp_result[5]=temp_result[4] + temp_array[3] - temp_array[6];
            temp_result[6]=temp_result[5] + temp_array[2] - temp_array[5];
            temp_result[7]=temp_result[6] + temp_array[1] - temp_array[4];
            result=(int)GetMax_float(temp_result,8);
            //将2个模板的平方的和的sprt
            if (result>255)
            {
                result=255;
            }
//可以对阈值进行处理
            *pdest= result;        
           
        }
    }   
    memcpy(pbmpdata,pNewbmpdata,ImageSize);
    free(pNewbmpdata);
    return TRUE;
}
一个是按照原有的思路做的,速度很慢
//************************************************************************************
//kirsch边缘检测算子
//************************************************************************************
BOOL ImgEdge_Kirsch(BITMAPINFO* pbmpinfo,BYTE* pbmpdata)
{
    LONG imagewidth=(int)pbmpinfo->bmiHeader.biWidth;
    LONG imageheigth=(int)pbmpinfo->bmiHeader.biHeight;
    //image size
    LONG  Linebyte =( pbmpinfo->bmiHeader.biBitCount * imagewidth +31)/32*4;
    LONG  ImageSize=Linebyte * imageheigth;
    //data is not null
    if (pbmpdata == NULL)
    {
        return FALSE;
    }
    //color must be gray
    if (pbmpinfo->bmiHeader.biBitCount != 8)
    {
        AfxMessageBox("只对灰度图像进行操作!");
        return FALSE;
    }
        //copy
    BYTE *pNewbmpdata=(BYTE*)malloc(ImageSize);
    if (pNewbmpdata == NULL)
    {
        return FALSE;
    }
    memcpy(pNewbmpdata,pbmpdata,ImageSize);
   
    //memset(pNewbmpdata,255,ImageSize);
        //注意数组不要越界,不对右边和下边的数据进行处理
    LONG width=0,heigth=0;
    BYTE *psrc=NULL;
    BYTE *pdest=NULL;
    int template_box[8][8]={
        {5,5,5,-3,-3,-3,-3,-3},
        {-3,5,5,5,-3,-3,-3,-3},
        {-3,-3,5,5,5,-3,-3,-3},
        {-3,-3,-3,5,5,5-3,-3},
        {-3,-3,-3,-3,5,5,5,-3},
        { -3,-3,-3,-3,-3,5,5,5},
        {5,-3,-3,-3,-3,-3,5,5},
        {5,5,-3,-3,-3,-3,-3,5}
    };
   
   
    int   temp_array[8]={0};
   
    int   temp_result[8]={0};
   
   
    int result=0;
    int i=0,j=0;
    for (heigth = 1; heigth < imageheigth - 1 ; heigth++)
    {
        for (width=1; width < imagewidth - 1; width++)
        {
            psrc  =  pbmpdata + ImageSize- Linebyte*heigth - Linebyte + width;
            pdest =  pNewbmpdata+ImageSize- Linebyte*heigth - Linebyte + width;
            //这里没有使用模板来做,减少寻址的次数
                        temp_array[0]= *(psrc-Linebyte-1);
            temp_array[1]= *(psrc-Linebyte);
            temp_array[2]= *(psrc-Linebyte+1);
            temp_array[3]= *(psrc+1);
            temp_array[4]= *(psrc+Linebyte+1);
            temp_array[5]= *(psrc+Linebyte);
            temp_array[6]= *(psrc+Linebyte-1);
            temp_array[7]= *(psrc-1);
           
            for (i=0;i<8;i++)
            {     
                temp_result[i]=0;
                for (j=0;j<8;j++)
                {
                    temp_result[i] += template_box[i][j]*temp_array[j];
                }
                    
            }
               
            //将2个模板的平方的和的sprt
            result=GetMax_int(temp_result,8);
           
            if (result>255)
            {
                result=255;
            }
            //可以对阈值进行处理
            *pdest= result;        
           
        }
    }
   
    memcpy(pbmpdata,pNewbmpdata,ImageSize);
    free(pNewbmpdata);
    return TRUE;
}

博主
zhangshaobing517@163.com
深夜孤灯's Blog
最新博客http://hi.baidu.com/zsb517/欢迎访问!
点击跳转