圖像預處理第3步:梯度銳化

圖像銳化的主要目的有兩個:
一是加強圖像邊緣,使模糊的圖像變得更加清晰,顏色變得鮮明突出,圖像的質量有所改善,產生更適合人眼觀察和識別的圖像;二是但願通過銳化處理後,目標物體的邊緣鮮明,以便於提取目標的邊緣、對圖像進行分割、目標區域識別、區域形狀提取等,爲進一步的圖像理解與分析奠基基礎。
圖像銳化通常有兩種方法:一是微分法,二是高通濾波法。高通濾波法的工做原理和低通濾波類似,這裏再也不贅述。下面主要介紹一下兩種經常使用的微分銳化方法:梯度銳化和拉普拉斯銳化。但因爲銳化使噪聲受到比信號還要強的加強,因此要求銳化處理的圖像有較高的信噪比;不然,銳化後圖像的信噪比更低。函數

//圖像預處理第3步:梯度銳化
void CChildView::OnImgprcSharp() 
{
    GradientSharp(m_hDIB);
    //在屏幕上顯示位圖
    CDC* pDC=GetDC();
    DisplayDIB(pDC,m_hDIB);        
}
/***********************************************
*
* 函數名稱:
*   GradientSharp() 
*
*參數 :
*  HDIB hDIB    -待處理圖像的句柄
*
* 返回值:
*       無
* 
*功能:
*    現圖像的梯度銳化

*說明:
*    只能對2值圖像進行處理,若是圖像自己邊緣較細,可能形成信息的損失
**********************************************************************/
void GradientSharp(HDIB hDIB)
{
    // 指向DIB的指針
    LPSTR lpDIB=(LPSTR) ::GlobalLock((HGLOBAL)hDIB);

    // 指向DIB象素指針
    LPSTR    lpDIBBits;    

    // 找到DIB圖像象素起始位置
    lpDIBBits = ::FindDIBBits(lpDIB);    

    //獲取圖像的寬度
    LONG lWidth=::DIBWidth ((char*)lpDIB);

    //獲取圖像的長度
    LONG lHeight=::DIBHeight ((char*)lpDIB);

    // 閾值
    BYTE    bThre = 2;

    // 調用GradSharp()函數進行梯度板銳化

    // 指向源圖像的指針
    unsigned char*    lpSrc;
    unsigned char*    lpSrc1;
    unsigned char*    lpSrc2;
    
    // 循環變量
    LONG    i;
    LONG    j;
    
    // 圖像每行的字節數
    LONG    lLineBytes;
    
    // 中間變量
    BYTE    bTemp;
    
    // 計算圖像每行的字節數
    lLineBytes = WIDTHBYTES(lWidth * 8);
    
    // 每行
   for(i = 0; i < lHeight; i++)
    {
        
     // 每列
     for(j = 0; j < lWidth; j++)
        {
            
             // 指向DIB第i行,第j個象素的指針
            lpSrc  = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
            
            // 指向DIB第i+1行,第j個象素的指針
            lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j;
            
             // 指向DIB第i行,第j+1個象素的指針
             lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 1;
            

              //計算梯度值
             bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2));
            
            // 判斷是否小於閾值
            if (bTemp < 255)
            {  

             // 判斷是否大於閾值,對於小於狀況,灰度值不變。
               if (bTemp >= bThre)
               {

            // 直接賦值爲bTemp
             *lpSrc = bTemp;

               }

            }
            
           else
            {
                // 直接賦值爲255
                *lpSrc = 255;
            }
     }
   }

//最後還要處理一下圖像中最下面那行
for(j = 0; j < lWidth; j++)
{   
    
 //指向最下邊一行,第j個象素的指針
  lpSrc  = (unsigned char*)lpDIBBits + lLineBytes * 0 + j;

   //將此位置的象素設置爲255,即白點
    *lpSrc=255;
}

   //解除鎖定
    ::GlobalUnlock ((HGLOBAL)hDIB);
}

運行效果:spa


參考資料:
梯度銳化 http://blog.csdn.net/xiaofengsheng/article/details/4777591.net

相關文章
相關標籤/搜索