图像预处理第4步:去离散杂点噪声

//图像预处理第4步:去离散杂点噪声
void CChildView::OnImgprcRemoveNoise() 
{
    RemoveScatterNoise(m_hDIB);
    //在屏幕上显示位图
    CDC* pDC=GetDC();
    DisplayDIB(pDC,m_hDIB);    
}
/************************************************************
*
*  函数名称:
*       RemoveScatterNoise()
*
*  参数:
*     HDIB    hDIB     -原图像的句柄
*
*  返回值:
*       无
*
*  功能:
*     通过对连续点长度的统计来去除离散杂点
*
*  说明:
*      只能对2值图像进行处理
****************************************************************/
void RemoveScatterNoise(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);

    //设置判定噪声的长度阈值为15
    //即如果与考察点相连接的黑点的数目小于15则认为考察点是噪声点
    int length=15;
    
    // 循环变量
    m_lianXuShu=0;
    LONG    i;
    LONG    j;    
    LONG    k;

    // 图像每行的字节数
    LONG    lLineBytes;

    // 计算图像每行的字节数
    lLineBytes = WIDTHBYTES(lWidth * 8);

    
    LPSTR lpSrc;

    //开辟一块用来存放标志的内存数组
    LPBYTE lplab = new BYTE[lHeight * lWidth];

    //开辟一块用来保存离散判定结果的内存数组
    bool *lpTemp = new bool[lHeight * lWidth];

    //初始化标志数组
    for (i=0;i<lHeight*lWidth;i++)
    {

    //将所有的标志位设置为非
    lplab[i] = false;

    }

    //用来存放离散点的坐标的数组
    CPoint lab[21];
   
    //为循环变量赋初始值
    k=0;

    //扫描整个图像

    //逐行扫描
    for(i =0;i<lHeight;i++)
    {  
       
       //逐行扫描
        for(j=0;j<lWidth;j++)
            {    
                //先把标志位置false
                for(k=0;k<m_lianXuShu;k++)
                lplab[lab[k].y * lWidth + lab[k].x] = false;

                //连续数置0
                m_lianXuShu =0;

                //进行离散性判断
                lpTemp[i*lWidth+j] = DeleteScaterJudge(lpDIBBits,(WORD)lLineBytes,lplab,lWidth,lHeight,j,i,lab,length);

            }
    }
            
    //扫描整个图像,把离散点填充成白色

    //逐行扫描
    for(i = 0;i<lHeight;i++)
    {

      //逐列扫描
        for(j=0;j<lWidth;j++)
        {       
                //查看标志位,如果为非则将此点设为白点
                if(lpTemp[i*lWidth+j] == false)
                {    
                   //指向第i行第j个象素的指针
                    lpSrc=(char*)lpDIBBits + lLineBytes * i + j;

                    //将此象素设为白点
                    *lpSrc=BYTE(255);
                }
            }
    }

    //解除锁定
    ::GlobalUnlock ((HGLOBAL)hDIB);

}

运行效果:

posted @ 2016-04-19 15:17  Bobby0322  阅读(2500)  评论(0编辑  收藏  举报