进行识别前图像预处理.docx
《进行识别前图像预处理.docx》由会员分享,可在线阅读,更多相关《进行识别前图像预处理.docx(18页珍藏版)》请在冰豆网上搜索。
进行识别前图像预处理
进行识别前图像预处理
//BP神经网络字符识别函数定义
#include"dibapi.h"
#include<iostream>
#include<deque>
#include<math.h>
usingnamespacestd;
typedefdeque<CRect>CRectLink;
typedefdeque<HDIB>HDIBLink;
//声明一些必要的全局变量
intw_sample=8;
inth_sample=16;
boolfileloaded;
boolgyhinfoinput;
boolgyhfinished;
intdigicount;
intm_lianXuShu;
CRectLinkm_charRectCopy;
CRectLinkm_charRect;
HDIBLinkm_dibRect;
HDIBLinkm_dibRectCopy;
HDIBm_hDIB;
CStringstrPathName;
CStringstrPathNameSave;
/********************************functiondeclaration*************************************/
//清楚屏幕
voidClearAll(CDC*pDC);
//在屏幕上显示位图
voidDisplayDIB(CDC*pDC,HDIBhDIB);
//对分割后的位图进行尺寸标准归一化
voidStdDIBbyRect(HDIBhDIB,inttarWidth,inttarHeight);
//整体斜率调整
voidSlopeAdjust(HDIBhDIB);
//去除离散噪声点
voidRemoveScatterNoise(HDIBhDIB);
//梯度锐化
voidGradientSharp(HDIBhDIB);
//画框
voidDrawFrame(CDC*pDC,HDIBhDIB,CRectLinkcharRect,unsignedintlinewidth,COLORREFcolor);
//将灰度图二值化
voidConvertGrayToWhiteBlack(HDIBhDIB);
//将256色位图转为灰度图
voidConvert256toGray(HDIBhDIB);
//细化
voidThinning(HDIBhDIB);
//对位图进行分割.返回一个存储着每块分割区域的链表
CRectLinkCharSegment(HANDLEhDIB);
//紧缩、重排调整
HDIBAutoAlign(HDIBhDIB);
//判断是否是离散噪声点
boolDeleteScaterJudge(LPSTRlpDIBBits,WORDlLineBytes,LPBYTElplab,intlWidth,intlHeight,intx,inty,CPointlab[],intlianXuShu);
//对图像进行模板操作
HDIBTemplate(HDIBhDIB,double*tem,inttem_w,inttem_h,doublexishu);
//对图像进行中值滤波
HDIBMidFilter(HDIBhDIB,inttem_w,inttem_h);
//对图像进行直方图均衡
voidEqualize(HDIBhDIB);
/***********************************implementation*************************************/
/***********************************************************************
函数名称:
DisplayDIB
参数:
CDC*pDC-指向当前设备上下文(DiviceContext)的指针
HDIBhDIB-要显示的位图的句柄
**********************************************************************/
voidDisplayDIB(CDC*pDC,HDIBhDIB)
{
BYTE*lpDIB=(BYTE*):
:
GlobalLock((HGLOBAL)hDIB);
//获取DIB宽度和高度
intcxDIB=:
:
DIBWidth((char*)lpDIB);
intcyDIB=:
:
DIBHeight((char*)lpDIB);
CRectrcDIB,rcDest;
rcDIB.top=rcDIB.left=0;
rcDIB.right=cxDIB;
rcDIB.bottom=cyDIB;
//设置目标客户区输出大小尺寸
rcDest=rcDIB;
//CDC*pDC=GetDC();
ClearAll(pDC);
//在客户区显示图像
//for(intii=0;ii<10;ii++)
:
:
PaintDIB(pDC->m_hDC,rcDest,hDIB,rcDIB,NULL);
:
:
GlobalUnlock((HGLOBAL)hDIB);
}
voidClearAll(CDC*pDC)
{
CRectrect;
//GetClientRect(&rect);
rect.left=0;rect.top=0;rect.right=2000;rect.bottom=1000;
CPenpen;
pen.CreatePen(PS_SOLID,1,RGB(255,255,255));
pDC->SelectObject(&pen);
pDC->Rectangle(&rect);
:
:
DeleteObject(pen);
}
/*******************************************
*
*函数名称:
*AutoAlign()
*
*参数:
*HDIBhDIB-原图像的句柄
*
*返回值
*HDIB-紧缩排列后的新图像的句柄
*
*功能:
*将经过了标准化处理的字符进行规整的排列,以方便下一步的处理
*
*说明:
*紧缩排列的操作必须在标准化操作之后进行
*
********************************************************/
HDIBAutoAlign(HDIBhDIB)
{
//指向图像的指针
BYTE*lpDIB=(BYTE*):
:
GlobalLock((HGLOBAL)hDIB);
//指向象素起始位置的指针
BYTE*lpDIBBits=(BYTE*):
:
FindDIBBits((char*)lpDIB);
//指向象素的指针
BYTE*lpSrc;
//获取图像的宽度
LONGlWidth=:
:
DIBWidth((char*)lpDIB);
//获取图像的高度
LONGlHeight=:
:
DIBHeight((char*)lpDIB);
//获取标准化的宽度
intw=m_charRect.front().Width();
//获取标准化的高度
inth=m_charRect.front().Height();
//建立一个新的图像正好能够将标准化的字符并排放置
HDIBhNewDIB=:
:
NewDIB(digicount*w,h,8);
//指向新的图像的指针
BYTE*lpNewDIB=(BYTE*):
:
GlobalLock((HGLOBAL)hNewDIB);
//指向象素起始位置的指针
BYTE*lpNewDIBBits=(BYTE*):
:
FindDIBBits((char*)lpNewDIB);
//指向象素的指针
BYTE*lpDst=lpNewDIBBits;
//计算原图像每行的字节数
LONGlLineBytes=(lWidth+3)/4*4;
//计算新图像每行的字节数
LONGlLineBytesnew=(digicount*w+3)/4*4;
//将新的图像初始化为白色
memset(lpDst,(BYTE)255,lLineBytesnew*h);
//映射操作的坐标变量
inti_src,j_src;
//循环变量
inti,j;
//统计字符个数的变量
intcounts=0;
//存放位置信息的结构体
CRectrect,rectnew;
//清空一个新的链表来存放新的字符位置信息
m_charRectCopy.clear();
//从头至尾逐个扫描原链表的各个结点
while(!
m_charRect.empty())
{
//从表头上得到一个矩形框
rect=m_charRect.front();
//将这个矩形框从链表上删除
m_charRect.pop_front();
//计算新的矩形框的位置信息
//左边界
rectnew.left=counts*w;
//右边界
rectnew.right=(counts+1)*w;
//上边界
rectnew.top=0;
//下边界
rectnew.bottom=h;
//将获得的新的矩形框插入到新的链表中
m_charRectCopy.push_back(rectnew);
//将原矩形框内的象素映射到新的矩形框中
for(i=0;i<h;i++)
{
for(j=counts*w;j<(counts+1)*w;j++)
{
//计算映射坐标
i_src=rect.top+i;
j_src=rect.left+j-counts*w;
//进行象素的映射
lpSrc=(BYTE*)lpDIBBits+lLineBytes*i_src+j_src;
lpDst=(BYTE*)lpNewDIBBits+lLineBytesnew*i+j;
*lpDst=*lpSrc;
}
}
//字符个数加1
counts++;
}
//将获得的新的链表复制到原链表中,以方便下一次的调用
m_charRect=m_charRectCopy;
//解除锁定
:
:
GlobalUnlock(hDIB);
:
:
GlobalUnlock(hNewDIB);
returnhNewDIB;
}
/**************************************************
*函数名称:
*ThinnerHilditch
*
*参数:
*void*image-二值化图像矩阵前景色为1背景色为0
*unsignedlonglx-图像的宽度
*unsignedlongly-图像的高度
*
*返回值
*无
*
*函数功能:
*对输入的图像进行细化,输出细化后的图像
***********************************************************/
voidThinnerHilditch(void*image,unsignedlonglx,unsignedlongly)
{
char*f,*g;
charn[10];
unsignedintcounter;
shortk,shori,xx,nrn;
unsignedlongi,j;
longkk,kk11,kk12,kk13,kk21,kk22,kk23,kk31,kk32,kk33,size;
size=(long)lx*(long)ly;
g=(char*)malloc(size);
if(g==NULL)
{
//printf("errorinallocatingmemory!
\n");
return;
}
f=(char*)image;
for(i=0;i<lx;i++)
{
for(j=0;j<ly;j++)
{
kk=i*ly+j;
if(f[kk]!
=0)
{
f[kk]=1;
g[kk]=f[kk];
}
}
}
counter=1;
do
{
counter++;
shori=0;
for(i=0;i<lx;i++)
{
for(j=0;j<ly;j++)
{
kk=i*ly+j;
if(f[kk]<0)
f[kk]=0;
g[kk]=f[kk];
}
}
for(i=1;i<lx-1;i++)
{
for(j=1;j<ly-1;j++)
{
kk=i*ly+j;
if(f[kk]!
=1)
continue;
kk11=(i-1)*ly+j-1;
kk12=kk11+1;
kk13=kk12+1;
kk21=i*ly+j-1;
kk22=kk21+1;
kk23=kk22+1;
kk31=(i+1)*ly+j-1;
kk32=kk31+1;
kk33=kk32+1;
if((g[kk12]&&g[kk21]&&g[kk23]&&g[kk32])!
=0)
continue;
nrn=g[kk11]+g[kk12]+g[kk13]+g[kk21]+g[kk23]+
g[kk31]+g[kk32]+g[kk33];
if(nrn<=1)
{
f[kk22]=2;
continue;
}
n[4]=f[kk11];
n[3]=f[kk12];
n[2]=f[kk13];
n[5]=f[kk21];
n[1]=f[kk23];
n[6]=f[kk31];
n[7]=f[kk32];
n[8]=f[kk33];
n[9]=n[1];
xx=0;
for(k=1;k<8;k=k+2)
{
if((!
n[k])&&(n[k+1]||n[k+2]))
xx++;
}
if(xx!
=1)
{
f[kk22]=2;
continue;
}
if(f[kk12]==-1)
{
f[kk12]=0;
n[3]=0;
xx=0;
for(k=1;k<8;k=k+2)
{
if((!
n[k])&&(n[k+1]||n[k+2]))
xx++;
}
if(xx!
=1)
{
f[kk12]=-1;
continue;
}
f[kk12]=-1;
n[3]=-1;
}
if(f[kk21]!
=-1)
{
f[kk22]=-1;
shori=1;
continue;
}
f[kk21]=0;
n[5]=0;
xx=0;
for(k=1;k<8;k=k+2)
{
if((!
n[k])&&(n[k+1]||n[k+2]))
{
xx++;
}
}
if(xx==1)
{
f[kk21]=-1;
f[kk22]=-1;
shori=1;
}
else
f[kk21]=-1;
}
}
}while(shori);
free(g);
}
/**************************************************
*函数名称:
*ThinnerRosenfeld
*
*参数:
*void*image-二值化图像矩阵前景色为1背景色为0
*unsignedlonglx-图像的宽度
*unsignedlongly-图像的高度
*
*返回值
*无
*
*函数功能:
*对输入的图像进行细化,输出细化后的图像
***********************************************************/
voidThinnerRosenfeld(void*image,unsignedlonglx,unsignedlongly)
{
char*f,*g;
charn[10];
chara[5]={0,-1,1,0,0};
charb[5]={0,0,0,1,-1};
charnrnd,cond,n48,n26,n24,n46,n68,n82,n123,n345,n567,n781;
shortk,shori;
unsignedlongi,j;
longii,jj,kk,kk1,kk2,kk3,size;
size=(long)lx*(long)ly;
g=(char*)malloc(size);
if(g==NULL)
{
printf("errorinalocatingmmeory!
\n");
return;
}
f=(char*)image;
for(kk=0l;kk<size;kk++)
{
g[kk]=f[kk];
}
do
{
shori=0;
for(k=1;k<=4;k++)
{
for(i=1;i<lx-1;i++)
{
ii=i+a[k];
for(j=1;j<ly-1;j++)
{
kk=i*ly+j;
if(!
f[kk])
continue;
jj=j+b[k];
kk1=ii*ly+jj;
if(f[kk1])
continue;
kk1=kk-ly-1;
kk2=kk1+1;
kk3=kk2+1;
n[3]=f[kk1];
n[2]=f[kk2];
n[1]=f[kk3];
kk1=kk-1;
kk3=kk+1;
n[4]=f[kk1];
n[8]=f[kk3];
kk1=kk+ly-1;
kk2=kk1+1;
kk3=kk2+1;
n[5]=f[kk1];
n[6]=f[kk2];
n[7]=f[kk3];
nrnd=n[1]+n[2]+n[3]+n[4]
+n[5]+n[6]+n[7]+n[8];
if(nrnd<=1)
continue;
cond=0;
n48=n[4]+n[8];
n26=n[2]+n[6];
n24=n[2]+n[4];
n46=n[4]+n[6];
n68=n[6]+n[8];
n82=n[8]+n[2];
n123=n[1]+n[2]+n[3];
n345=n[3]+n[4]+n[5];
n567=n[5]+n[6]+n[7];
n781=n[7]+n[8]+n[1];