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;
}
本文介绍了一种图像处理中的离散点剔除算法,通过递归方式判定并去除图像中的孤立噪声点,提高图像质量。
&spm=1001.2101.3001.5002&articleId=12612203&d=1&t=3&u=ca933743413c40b6a5177baf5d9ec274)
8462

被折叠的 条评论
为什么被折叠?



