图像预处理第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);
}

运行效果:

  调整前

调整后

原文地址:https://www.cnblogs.com/Bobby0322/p/5408377.html