📄 mydiblib.h
字号:
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x,y-1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//左下点
lpSrc=(char*)lpDIBBits + lLineBytes * (y-1) + x-1;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(y-1 >=0 && x-1 >=0 && gray== 0 && lplab[(y-1)*lWidth+x-1] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x-1,y-1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//左边
lpSrc=(char*)lpDIBBits + lLineBytes * y + x-1;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(x-1 >=0 && gray== 0 && lplab[y*lWidth+x-1] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x-1,y,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//左上
lpSrc=(char*)lpDIBBits + lLineBytes * (y+1) + x-1;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(y+1 <lHeight && x-1 >= 0 && gray == 0 && lplab[(y+1)*lWidth+x-1] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x-1,y+1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//上面
lpSrc=(char*)lpDIBBits + lLineBytes * (y+1) + x;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(y+1 < lHeight && gray == 0 && lplab[(y+1)*lWidth+x] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x,y+1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//右上
lpSrc=(char*)lpDIBBits + lLineBytes * (y+1) + x+1;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(y+1 <lHeight && x+1 <lWidth && gray == 0 && lplab[(y+1)*lWidth+x+1] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x+1,y+1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//右边
lpSrc=(char*)lpDIBBits + lLineBytes * y + x+1;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(x+1 <lWidth && gray==0 && lplab[y*lWidth+x+1] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x+1,y,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//右下
lpSrc=(char*)lpDIBBits + lLineBytes * (y-1) + x+1;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(y-1 >=0 && x+1 <lWidth && gray == 0 && lplab[(y-1)*lWidth+x+1] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x+1,y-1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
}
//如果递归结束,返回false,说明是离散点
return FALSE;
}
/*****************绘制数字字符外面的矩形框*******************/
void DrawFrame(CDC* pDC,HDIB hDIB, CRectLink charRect,unsigned int linewidth,COLORREF color)
{
CPen pen;
pen.CreatePen (PS_SOLID,linewidth,color);
pDC->SelectObject (&pen);
::SelectObject (*pDC,GetStockObject(NULL_BRUSH));
CRect rect,rect2;
BYTE* lpDIB=(BYTE*)::GlobalLock ((HGLOBAL)hDIB);
while(!charRect.empty())
{
//从表头上得到一个矩形
rect2=rect= charRect.front();
//从链表头上面删掉一个
charRect.pop_front();
//注意,这里原先的rect是相对于图像原点(左下角)的,
//而在屏幕上绘图时,要转换以客户区为原点的坐标
rect.top =::DIBHeight ((char*)lpDIB)-rect2.bottom;
rect.bottom =::DIBHeight ((char*)lpDIB)-rect2.top ;
pDC->Rectangle (&rect);
}
::GlobalUnlock ((HGLOBAL)hDIB);
}
/***********************************************
*
* 函数名称:
* GradientSharp()
*
*参数 :
* HDIB hDIB -待处理图像的句柄
*
* 返回值:
* 无
*
*功能:
* 现图像的梯度锐化
*说明:
* 只能对2值图像进行处理,如果图像本身边缘较细,可能造成信息的损失
**********************************************************************/
void GradientSharp(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);
// 阈值
BYTE bThre = 2;
// 调用GradSharp()函数进行梯度板锐化
// 指向源图像的指针
unsigned char* lpSrc;
unsigned char* lpSrc1;
unsigned char* lpSrc2;
// 循环变量
LONG i;
LONG j;
// 图像每行的字节数
LONG lLineBytes;
// 中间变量
BYTE bTemp;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 每行
for(i = 0; i < lHeight; i++)
{
// 每列
for(j = 0; j < lWidth; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
// 指向DIB第i+1行,第j个象素的指针
lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j;
// 指向DIB第i行,第j+1个象素的指针
lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 1;
//计算梯度值
bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2));
// 判断是否小于阈值
if (bTemp < 255)
{
// 判断是否大于阈值,对于小于情况,灰度值不变。
if (bTemp >= bThre)
{
// 直接赋值为bTemp
*lpSrc = bTemp;
}
}
else
{
// 直接赋值为255
*lpSrc = 255;
}
}
}
//最后还要处理一下图像中最下面那行
for(j = 0; j < lWidth; j++)
{
//指向最下边一行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * 0 + j;
//将此位置的象素设置为255,即白点
*lpSrc=255;
}
//解除锁定
::GlobalUnlock ((HGLOBAL)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);
}
/*********************************************************
* 函数名称:
* 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -