zoukankan      html  css  js  c++  java
  • 图像预处理第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);
    }

    运行效果:

      调整前

    调整后

  • 相关阅读:
    CF1137C Museums Tour(tarjan+DP)
    Educational Codeforces Round 65 (Rated for Div. 2)
    Codeforces Round #559(Div.1)
    委托
    类库
    is 和 as 运算符
    面向对象 接口
    抽象类
    面向对象 多态
    访问修饰符 程序集 静态方法
  • 原文地址:https://www.cnblogs.com/Bobby0322/p/5408377.html
Copyright © 2011-2022 走看看