圖像預處理第5步:傾斜度調整

//圖像預處理第5步:傾斜度調整
void CChildView::OnImgprcAdjustSlope() 
{
    SlopeAdjust(m_hDIB);
    //在屏幕上顯示位圖
    CDC* pDC=GetDC();
    DisplayDIB(pDC,m_hDIB);    
}
/*********************************************************

* 函數名稱:
*         SlopeAdjust()
*
* 參數:
*     HDIB   hDIB       -原圖像的句柄
*
* 返回值:
*         無
*
* 功能:
*     經過對圖像左右半邊平均高度的統計來進行傾斜的調整
*
* 說明:
*      只能對2值圖像進行處理
*
****************************************************************/
void SlopeAdjust(HDIB hDIB)
{
    // 指向DIB的指針
    LPSTR lpDIB=(LPSTR) ::GlobalLock((HGLOBAL)hDIB);
    
    // 指向DIB象素指針
    LPSTR    lpDIBBits;    

    // 找到DIB圖像象素起始位置
    lpDIBBits = ::FindDIBBits(lpDIB);
    
    // 指向源圖像的指針
    unsigned char*    lpSrc;

    // 循環變量
    LONG    i;
    LONG    j;
    
    // 圖像每行的字節數
    LONG    lLineBytes;

    //圖像的長度
    LONG    lWidth;

    //圖像的寬度
    LONG    lHeight;

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

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

    // 計算圖像每行的字節數
    lLineBytes = WIDTHBYTES(lWidth * 8);
    
    //圖像左半邊的平均高度
    double leftaver=0.0;

   //圖像右半邊的平均高度
    double rightaver=0.0;

    //圖像的傾斜度
    double slope;

    //統計循環變量
    LONG counts=0;
    
    //掃描左半邊的圖像,求黑色象素的平均高度

    //
    for (i=0;i<lHeight;i++)
    {   

      //
        for (j=0;j<lWidth/2;j++)
        {
         
         //指向第i行第j個象素的指針    
         lpSrc=(unsigned char*)lpDIBBits + lLineBytes *  i + j;
      
         //若是爲黑點
         if (*lpSrc == 0)
         {
          
          //對其高度進行統計疊加
          counts +=lWidth/2 -j;
          leftaver += i*(lWidth/2 -j);

         }

        }
    }

    //計算平均高度
    leftaver /= counts;
    
    //將統計循環變量從新賦值
    counts =0;

    //掃描右半邊的圖像,求黑色象素的平均高度

    //
    for (i =0;i<lHeight;i++)
    {

       //
        for (j=lWidth/2;j<lWidth;j++)
        {
            //指向第i行第j個象素的指針
            lpSrc=(unsigned char*)lpDIBBits + lLineBytes *  i + j;

            //若是爲黑點
            if (*lpSrc == 0)
                {

                  //進行統計疊加
                    counts +=lWidth -j;
                    rightaver += i*(lWidth -j);
                }
            }
    }

    //計算右半邊的平均高度
    rightaver /= counts;
    
    //計算斜率
    slope = (leftaver - rightaver) / (lWidth/2);

    //指向新的圖像象素起始位置的指針
    LPSTR lpNewDIBBits;
   
    //指向新圖像的指針
    LPSTR lpDst;
    
    //新圖像的句柄
    HLOCAL nNewDIBBits=LocalAlloc(LHND,lLineBytes*lHeight);
    
    //鎖定內存
    lpNewDIBBits=(char*)LocalLock(nNewDIBBits);
    
    //指向新圖像象素的指針
    lpDst=(char*)lpNewDIBBits;
    
    //爲新圖像賦初始值
    memset(lpDst,(BYTE)255,lLineBytes*lHeight);
    
    //象素點的灰度值
    int gray;
    
    //位置映射值
    int i_src;

    //根據斜率,把當前新圖像的點映射到源圖像的點

    //
    for (i=0;i<lHeight;i++)
    {
        //
           for (j=0;j<lWidth;j++)
        {    
           //計算映射位置    
            i_src=int(i - (j-lWidth/2)*slope);

            //若是點在圖像外,象素置白色
            if (i_src <0 || i_src >=lHeight )
                gray = 255;

            else
            {    
                //不然到源圖像中找點,取得象素值

                //指向第i_src行第j個象素的指針
                lpSrc=(unsigned char *)lpDIBBits + lLineBytes *  i_src + j;
                gray = *lpSrc;
            }
            
            //把新圖像的點用獲得的象素值填充
            //指向第i行第j個象素的指針
            lpDst = (char *)lpNewDIBBits + lLineBytes * i + j;
            *lpDst=gray;
        }
    }

    // 將新的圖像的內容拷貝到舊的圖像中
    memcpy(lpDIBBits,lpNewDIBBits,lLineBytes*lHeight);

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

運行效果:函數

  調整前spa

調整後指針

相關文章
相關標籤/搜索