📄 dipview.cpp
字号:
{
int row=0;
int col=0;
float alph=0.0;
int*E=new int[width];
long double*MSE=new long double[9]; //针对每一个alph的deltl;
//统计各列白象素个数
for(col=0;col<width;col++)
{
for(row=0;row<height;row++)
{
if(DisposeImg[row*width+col]==255)
projArray[col]++;
}
}
//一次平滑
for(int x=1;x<10;x++)
{
alph=(float)(0.1*x);
E[0]=projArray[0];
for(col=1;col<width;col++)
{
E[col]=(int)(alph*projArray[col]+(1-alph)*E[col-1]);
}
for(col=0;col<width;col++)
{
MSE[x-1]+=(projArray[col]-E[col])*(projArray[col]-E[col]);
}
MSE[x-1]=MSE[x-1]/width;
}
long double min=0.0;
for(x=1;x<10;x++)
{
if(MSE[x-1]>min)
{
min=MSE[x-1];
}
}
for(x=1;x<10;x++)
{
if(MSE[x-1]==min)
{
alph=(float)(0.1*x);
}
}
E[0]=projArray[0];
for(col=1;col<width;col++)
{
E[col]=(int)(alph*projArray[col]+(1-alph)*E[col-1]);
}
for(col=1;col<width;col++)
{
projArray[col]=E[col];
E[col]=0;
}
//二次平滑
for(x=1;x<10;x++)
{
alph=(float)(0.1*x);
E[0]=projArray[0];
for(col=1;col<width;col++)
{
E[col]=(int)(alph*projArray[col]+(1-alph)*E[col-1]);
}
for(col=0;col<width;col++)
{
MSE[x-1]+=(projArray[col]-E[col])*(projArray[col]-E[col]);
}
MSE[x-1]=MSE[x-1]/width;
}
min=0.0;
for(x=1;x<10;x++)
{
if(MSE[x-1]<min)
{
min=MSE[x-1];
}
}
for(x=1;x<10;x++)
{
if(MSE[x-1]==min)
{
alph=(float)(0.1*x);
}
}
E[0]=projArray[0];
for(col=1;col<width;col++)
{
E[col]=(int)(alph*projArray[col]+(1-alph)*E[col-1]);
}
for(col=1;col<width;col++)
{
projArray[col]=E[col];
E[col]=0;
}
//寻找波谷进行分割trough
FindTrough(projArray,width); //获得波谷位置
free(E);
free(MSE);
}
// 寻找波谷,划分字符区间
void CDipView::FindTrough(int* Array, int size)
{
int col=0;
bool*flage=new bool[size];
bool LFlage=false; //a wave start leftside
bool RFlage=false; //a wave end rightside
int LSide=0; //left side
int RSide=0; //right side
int length=0; //area width
for(col=0;col<size;col++)
{
flage[col]=false;
}
for(col=1;col<size-1;col++)
{
if(Array[col]==0&&Array[col+1]!=0&&LFlage==false)
{
flage[col]=true;
LFlage=true;
}
if((Array[col-1]!=0)&&(Array[col]==0)&&(LFlage==true)&&(RFlage==false))
{
flage[col]=true;
RFlage=true;
}
if((LFlage==true)&&(RFlage==true))
{
LFlage=false;
RFlage=false;
}
}
for(col=0;col<size;col++)
{
Array[col]=0;
if(flage[col]==true)
{
Array[col]=1;
}
}
}
// 分割字符
void CDipView::CharacterSplit(int* Array, int size)
{
CDipDoc *pDoc=GetDocument();
int width,height;
width=pDoc->ImgWidth;
height=pDoc->ImgHeight;
int x=Rect_X[0];
int y=Rect_Y[0];
int w=Rect_W[0];
int h=Rect_H[0];
int num=0;
for(num=0;num<10;num++)
{
cRects[num].x=-1;
cRects[num].y=-1;
cRects[num].w=0;
cRects[num].h=0;
}
bool flage=false;
int row=0;
int col=0;
int area=0;
num=0;
for(col=0;col<size;col++)
{
if(Array[col]==1)
{
num++;
if(num%2!=0&&flage==false)
{
flage=true;
cRects[area].x=x+col;
}
else if(num%2==0&&flage==true)
{
flage=false;
cRects[area].w=col-(cRects[area].x-x);
cRects[area].y=y;
cRects[area].h=h;
area++;
}
}
}
CharacterNum=area;
// CharacterNum=area+1;
for(;area>=0;area--)
{
if(cRects[area].w!=0)
{
for(row=cRects[area].y;row<(cRects[area].y+cRects[area].h);row++) //draw vertical line
{
pDoc->ImgData[row*width+cRects[area].x-1]=255;
pDoc->ImgData[row*width+(cRects[area].x+cRects[area].w)]=255;
}
for(col=cRects[area].x;col<(cRects[area].x+cRects[area].w);col++) //draw horizontal line
{
pDoc->ImgData[(cRects[area].y-1)*width+col]=255;
pDoc->ImgData[(cRects[area].y+cRects[area].h)*width+col]=255;
}
}
}
//save character
for(area=CharacterNum;area>=0;area--)
{
cDatas[area].w=cRects[area].w;
cDatas[area].h=cRects[area].h;
cDatas[area].Img=new BYTE[cRects[area].w*cRects[area].h];
for(row=cRects[area].y;row<(cRects[area].y+cRects[area].h);row++) //draw vertical line
{
for(col=cRects[area].x;col<(cRects[area].x+cRects[area].w);col++) //draw horizontal line
{
cDatas[area].Img[(row-cRects[area].y)*cRects[area].w+(col-cRects[area].x)]=pDoc->ImgData[row*width+col];
}
}
}
}
/*
// 读取样本库,传入一个sample类型的数组(从文件里读出的样本数据将放入其中),返回值为样本个数
int CDipView::LoadCharLib(sample* sa)
{
CFile cf;
if(cf.Open(".\\mydata.dat",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==0)
{
AfxMessageBox("打开文件失败,\n您最好退出程序");
}
int num=0;
try
{
sample sampleTemp;
cf.SeekToBegin();
DWORD dwBytesRemaining=(DWORD)(cf.GetLength());
while(dwBytesRemaining)
{
UINT nBytesRead=cf.Read(&sampleTemp,sizeof(sample));
sa[num]=sampleTemp;
dwBytesRemaining-=nBytesRead;
num++;
}
CString s;
// s.Format("共读取数据%d个,最后一个的序列号为%d",
// num,sampleTemp.serialnum);
// AfxMessageBox(s);
}
catch(CFileException *e)
{
e->ReportError();
e->Delete();
}
cf.Close();
return num;
}
// 缩放算法,一律缩放为20*36
void CDipView::Zoom(BYTE* DisposeImg, int width, int height)
{
if ((width==20)&&(height==36))
return;
// 源图像的宽度和高度
LONG lWidth=width;
LONG lHeight=height;
BYTE *temp_img=new BYTE[width*height];
// 循环变量
int i;
int j;
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
temp_img[j+i*width]=DisposeImg[j+i*width];
}
}
// 缩放后图像的宽度和高度
LONG lNewWidth;
LONG lNewHeight;
float XZRatio=(float)( 20.0/(float)(width));
float YZRatio=(float)(36.0/(float)(height));
// 象素在源坐标
LONG i0;
LONG j0;
//归一后的大小
lNewWidth = 20;
lNewHeight = 36;
height=lNewHeight;
width=lNewWidth;
for(i = 0;i< lNewHeight;i++)
{
for(j = 0;j< lNewWidth;j++)
{
i0 = (LONG) (i / YZRatio + 0.5);
j0 = (LONG) (j / XZRatio + 0.5);
// 判断是否在源图范围内
if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight))
{
// 复制象素
DisposeImg[j+i*lWidth] = temp_img[j0 + i0*lWidth];
}
else
{
// 对于源图中没有的象素,直接赋值为255
// DisposeImg[j+i*lWidth] = 0;
}
}
}
delete [] temp_img;
}
// 二值化算法,二值化为0和1两种值
void CDipView::BinaryImg(BYTE* DisposeImg, int width , int height)
{
BYTE *temp=new BYTE[height*width];
int x,y;
CopyImg(DisposeImg,temp,width,height);
long double total=0;
float aver=0;
for(x=0;x<height;x++)
{
for(y=0;y<width;y++)
{
total+=DisposeImg[x*width+y];
}
}
aver=(BYTE)(total/(float)(height*width));
float delt;
float sub=0;
for(x=0;x<height;x++)
{
for(y=0;y<width;y++)
{
sub+=(DisposeImg[x*width+y]-aver)*(DisposeImg[x*width+y]-aver);
}
}
delt=(float)(sqrt(sub/(float)(height*width)));
BYTE judge;
judge=(BYTE)(delt+aver);
for(x=0;x<height;x++)
{
for(y=0;y<width;y++)
{
if(DisposeImg[(x*width)+y]>=judge)
{
DisposeImg[(x*width)+y]=(BYTE)1;
}
else
{
DisposeImg[(x*width)+y]=(BYTE)0;
}
}
}
free(temp);
}
// Hilditch细化算法
void CDipView::ThinnerHilditch(void* image, unsigned long lx, unsigned long ly)
{
char *f, *g;
char n[10];
unsigned int counter;
short k, shori, xx, nrn;
unsigned long i, j;
long kk, kk11, kk12, kk13, kk21, kk22, kk23, kk31, kk32, kk33, size;
size = (long)lx * (long)ly;
g = (char *)malloc(size);
if(g == NULL)
{
printf("error in allocating memory!\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
{
printf("%4d*",counter);
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);
}
// 细化算法
void CDipView::ThinImage(BYTE* image, int width, int height)
{
LONG x,y,k;
BYTE image1[10000];
k=0;
LONG digitWidth = width;
LONG digitHeight = height;
for(x=0; x<digitWidth; x++)
{
image[x*width+0] = (BYTE)0;
image[x*width+digitHeight-1] = (BYTE)0;
}
for(y=0; y<digitHeight; y++)
{
image[0*width+y] = (BYTE)0;
image[(digitWidth-1)*width+y] = (BYTE)0;
}
for(x=0; x<digitWidth; x++)
{
for(y=0; y<digitHeight; y++)
{
image1[k] = image[x*width+y];
if(image1[k] != 0)
image1[k] = (BYTE)1;
k++;
}
}
ThinnerHilditch((void *)image1, digitWidth, digitHeight);
k=0;
for(x=0; x<digitWidth; x++)
{
for(y=0; y<digitHeight; y++)
{
image[x*width+y] = image1[k];
if(image[x*width+y]!=0)
image[x*width+y] = (BYTE)1;
k++;
}
}
}
// 获取特征
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -