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

    运行效果:

      调整前

    调整后

  • 相关阅读:
    函数对象、名称空间与作用域
    函数
    leetcode语法练习(二)
    leetcode语法练习(一)
    字符编码与文件操作
    集合类型内置方法与总结
    列表,元组与字典类型
    数据类型内置方法之数据类型与字符串类型
    [SVG实战]饼图全面解析
    [JavaScript语法学习]重新认识JavaScript
  • 原文地址:https://www.cnblogs.com/Bobby0322/p/5408377.html
Copyright © 2020-2023  润新知