修改去噪函数----网上的去噪函数有问题,在此解决下,(颜色标注处)

本文介绍了一种图像处理中的离散点剔除算法,通过递归方式判定并去除图像中的孤立噪声点,提高图像质量。

void CIDcardRecogizeDlg::OnMenuQuzao1(BYTE* p_data, int width, int height)
{
 int test=0;
 // BYTE *p_data;     //原图数据区指针
 int Width = width;
 int Height = height;
    //取得原图的数据区指针
 // p_data=/*(BYTE *)*/m_pdata;
 
 //设置判定噪声的长度阈值为15
 //即如果与考察点相连接的黑点的数目小于15则认为考察点是噪声点
 int length=20;
 m_lianXuShu=0;
 // 循环变量
 LONG i;
 LONG j; 
 LONG    k;
 int LineBytes=(Width*8+31)/32*4; 
 
// LPSTR lpSrc;//LPSTR是MFC特有的数据类型,具体要根据编译环境的上下文来区别。通常情况下等同于char *
 BYTE *lpSrc;
 
 //开辟一块用来存放标志的内存数组
    BYTE *lplab = new BYTE[Height * LineBytes];
 memset(lplab,0,Height * LineBytes);

 //开辟一块用来保存离散判定结果的内存数组
 bool *lpTemp = new bool[Height * LineBytes];
 
    //初始化标志数组
 //将所有的标志位设置为非
 //memset(lplab,0,Height * LineBytes);
 for (i=0;i<Height * LineBytes;i++)
    {
  
  //将所有的标志位设置为非
  lplab[i] = false;
  
 }
 
 //用来存放离散点的坐标的数组
 CPoint lab[21];
 
 //为循环变量赋初始值
 k=0;
 
 //扫描整个图像
 
 //逐行扫描
 for(i =0;i<Height;i++)
 { 
  
  //逐列扫描
  for(j=0;j<Width;j++)
  {
   //先把标志位置false
   for(k=0;k<m_lianXuShu;k++)
   { 
    lplab[lab[k].y * Width + lab[k].x] = false;
   
   }
   
   //连续数置0
   m_lianXuShu =0;
   
   //进行离散性判断
   
   // TRACE("before:%d,%d\n",i,j);
//    WriteLog("strat1");
   lpTemp[i*Width+j] = DeleteScaterJudge1(p_data,(WORD)LineBytes,lplab,Width,Height,j,i,lab,length);
//    WriteLog("end1");
   // TRACE("after:%d,%d\n",i,j);
   
  }
 }
  
 //扫描整个图像,把离散点填充成白色
 
 //逐行扫描
 for(i = 0;i<Height;i++)
 {
  
  //逐列扫描
  for(j=0;j<Width;j++)
  {      
   //查看标志位,如果为非则将此点设为白点
   if(lpTemp[i*Width+j] == false)
   { 
    //指向第i行第j个象素的指针
    lpSrc=p_data + LineBytes * i + j;
    
    //将此象素设为白点
    *(lpSrc+0)=255;
    
   }
   
  }
 }
 // cvSaveImage("c:\\iptemp.bmp",p_data);
 delete lplab;
 delete lpTemp;
 // Invalidate();
// MessageBox("success2");
}

 

BOOL CIDcardRecogizeDlg::DeleteScaterJudge1(BYTE *p_data1, WORD lLineBytes, LPBYTE lplab, int lWidth, int lHeight, int x, int y, CPoint lab[], int lianXuShu)
{
 //如果连续长度满足要求,说明不是离散点,返回
  if(m_lianXuShu>=lianXuShu)
   return TRUE;
 
 //长度加一
 m_lianXuShu++;
 
 //设定访问标志
  lplab[lWidth * y +x] = true;
 
 //保存访问点坐标
  lab[m_lianXuShu-1].x = x;
 lab[m_lianXuShu-1].y = y;
 
 //象素的灰度值
 int gray;
 
 //指向象素的指针
  //LPSTR lpSrc;//LPSTR :一个32位指向字符串指针,相当于char *;
  BYTE *lpSrc;

  //长度判定
     //如果连续长度满足要求,说明不是离散点,返回
  if(m_lianXuShu>=lianXuShu)
  return TRUE;
  
 //下面进入递归
 else
 { 
  //考察上下左右以及左上、右上、左下、右下八个方向
  //如果是黑色点,则调用函数自身进行递归
  //考察下面点
  
   lpSrc=p_data1 + lLineBytes * (y-1) + x;
 
     if ((lLineBytes * (y-1) + x)>=0 )
     {
   //传递灰度值
   gray=*lpSrc;

     }
 
  //如果点在图像内、颜色为黑色并且没有被访问过
  if(y-1 >=0 && gray == 0 && lplab[(y-1)*lWidth+x] == false)    
    DeleteScaterJudge1(p_data1,lLineBytes,lplab,lWidth,lHeight,x,y-1,lab,lianXuShu);//进行递归处理 
 

   //判断长度
   //如果连续长度满足要求,说明不是离散点,返回
  if(m_lianXuShu>=lianXuShu)
    return TRUE;

   //左下点
  
  lpSrc=p_data1 + lLineBytes * (y-1) + x-1;
  if ((lLineBytes * (y-1) + x-1)>=0 )
  {
   //传递灰度值
   gray=*lpSrc;
   
  }

        //如果点在图像内、颜色为黑色并且没有被访问过
  if(y-1 >=0 &&  x-1 >=0 && gray== 0 && lplab[(y-1)*lWidth+x-1] == false)
         DeleteScaterJudge1(p_data1,lLineBytes,lplab,lWidth,lHeight,x-1,y-1,lab,lianXuShu);//进行递归处理
 

        //判断长度
  //如果连续长度满足要求,说明不是离散点,返回
   if(m_lianXuShu>=lianXuShu)
    return TRUE;
  
  //左边
   
   lpSrc=p_data1 + lLineBytes * y + x-1;

  if (x>=1)
  {
   //传递灰度值
   gray=*lpSrc;

  }
 
         //如果点在图像内、颜色为黑色并且没有被访问过
  if(x-1 >=0 &&  gray== 0 && lplab[y*lWidth+x-1] == false)
   DeleteScaterJudge1(p_data1,lLineBytes,lplab,lWidth,lHeight,x-1,y,lab,lianXuShu);//进行递归处理 
 

       //判断长度
   //如果连续长度满足要求,说明不是离散点,返回
   if(m_lianXuShu>=lianXuShu)
   return TRUE;
  
  //左上
   
   lpSrc=p_data1 + lLineBytes * (y+1) + x-1;
 
  if ((lLineBytes * (y+1) + x-1)>=0 && (y+1)!=lHeight )
  {  
   gray=*lpSrc;    //传递灰度值 
  }
 
        //如果点在图像内、颜色为黑色并且没有被访问过
  if(y+1 <lHeight && x-1 >= 0 && gray == 0 && lplab[(y+1)*lWidth+x-1] == false)   
  {
   DeleteScaterJudge1(p_data1,lLineBytes,lplab,lWidth,lHeight,x-1,y+1,lab,lianXuShu); //进行递归处理
  }
 

         //判断长度
  //如果连续长度满足要求,说明不是离散点,返回
   if(m_lianXuShu>=lianXuShu)
   return TRUE;
  
  //上面
  
  lpSrc=p_data1 + lLineBytes * (y+1) + x;

        if ((y+1)!=lHeight)
        {  
   gray=*lpSrc;//传递灰度值
        }
 
        //如果点在图像内、颜色为黑色并且没有被访问过
  if(y+1 < lHeight && gray == 0 && lplab[(y+1)*lWidth+x] == false)
  {
    DeleteScaterJudge1(p_data1,lLineBytes,lplab,lWidth,lHeight,x,y+1,lab,lianXuShu);//进行递归处理    
  }
  
         //判断长度
   //如果连续长度满足要求,说明不是离散点,返回
  if(m_lianXuShu>=lianXuShu)
   return TRUE;
   
  //右上
  
   lpSrc=p_data1 + lLineBytes * (y+1) + x+1;
        
   if((y+1)!=lHeight && (x+1)!=lWidth)
  {
   gray=*lpSrc;//传递灰度值
  }

        //如果点在图像内、颜色为黑色并且没有被访问过
   if(y+1 <lHeight && x+1 <lWidth &&  gray == 0 && lplab[(y+1)*lWidth+x+1] == false)
  {
   DeleteScaterJudge1(p_data1,lLineBytes,lplab,lWidth,lHeight,x+1,y+1,lab,lianXuShu);//进行递归处理
  }
 

        //判断长度
   //如果连续长度满足要求,说明不是离散点,返回
  if(m_lianXuShu>=lianXuShu)
    return TRUE;
  
  //右边
 
  lpSrc=p_data1 + lLineBytes * y + x+1;

  if( (x+1)!=lWidth)
  {
   gray=*lpSrc; //传递灰度值
  }

  //如果点在图像内、颜色为黑色并且没有被访问过
  if(x+1 <lWidth && gray==0 && lplab[y*lWidth+x+1] == false)
  {
   DeleteScaterJudge1(p_data1,lLineBytes,lplab,lWidth,lHeight,x+1,y,lab,lianXuShu);//进行递归处理
  }


       //判断长度

  //如果连续长度满足要求,说明不是离散点,返回
  if(m_lianXuShu>=lianXuShu)
   return TRUE;
   
   //右下
 
  lpSrc=p_data1 + lLineBytes * (y-1) + x+1;
  if((y-1)>=0 && (x+1)!=lWidth)
  {   
   gray=*lpSrc; //传递灰度值
  }

        //如果点在图像内、颜色为黑色并且没有被访问过
  if(y-1 >=0 && x+1 <lWidth && gray == 0 && lplab[(y-1)*lWidth+x+1] == false)
  {
   DeleteScaterJudge1(p_data1,lLineBytes,lplab,lWidth,lHeight,x+1,y-1,lab,lianXuShu);//进行递归处理
  }
         

        //判断长度
  //如果连续长度满足要求,说明不是离散点,返回
  if(m_lianXuShu>=lianXuShu)
    return TRUE;
  }
 //如果递归结束,返回false,说明是离散点
  return FALSE;


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值