基于模糊特征的文字识别+实现代码

基于模糊特征的文字识别实习原理如下:



代码如下:(在OPENCV环境下编写)

#pragma comment(lib, "opencv_imgproc220d.lib")  
#pragma comment(lib, "opencv_highgui231d.lib") 
#pragma comment(lib, "opencv_core231d.lib") 


#include "highgui.h"
#include <math.h>
#include <cv.h>
#include "stdio.h"
#include "stdlib.h"
#include "math.h"


#define N 26     //字母数量
#define dimNum 8  //向量维数
#define min(a, b) (a<b?a:b)
#define max(a, b) (a>b?a:b)


CvSize letterSize;
double letterVector[N][dimNum];


void getFuzzyVector(IplImage *srcPic);   //获取26个字母的迷糊向量
void letterMatch(IplImage *testPic);    //字母匹配
void fuzzyNearness(double *src);       //贴进度计算


void main()
{
IplImage *srcPic;
srcPic = cvLoadImage("1.bmp", 0);
if(srcPic==NULL)
{
printf("打开训练图片错误\n");
exit(0);
}


IplImage *testPic;
testPic = cvLoadImage("test.bmp", 0);
if(testPic==NULL)
{
printf("打开测试图片错误\n");
exit(0);
}

getFuzzyVector(srcPic);   //获取26个字母的模糊向量


letterMatch(testPic);    //字母匹配


cvShowImage("训练图片", srcPic);
cvShowImage("测试图片", testPic);
cvWaitKey(0);


cvDestroyAllWindows();
cvReleaseImage(&testPic);
cvReleaseImage(&srcPic);
}




//贴进度计算
void fuzzyNearness(double *src)
{
int i, j, laber;
double sum, maxNum;
double Y[N];
double temp[dimNum];
double minNum;
bool flag = false;
double innerMul[N];
double outerMul[N];


//欧几里得贴进度
for(i=0; i<N; i++)
{
sum = 0;
for(j=0; j<dimNum; j++)
sum += (src[j]-letterVector[i][j])*(src[j]-letterVector[i][j]);
Y[i] = 1-sqrtf(sum)/sqrtf(dimNum);
}


//输出结果
maxNum = Y[0];
laber = 0;
for(i=1; i<N; i++)
if(maxNum<Y[i])
{
maxNum = Y[i];
laber = i;
}


printf("%c  ", laber+65);
}




//字母匹配
void letterMatch(IplImage *testPic)
{
int i, j;
int flag = 0;


CvScalar scalar;
int xPixelNum, yPixelNum;
int yTop, yDown, xLeft, xRight;
int letterHeight, letterWidth;
CvPoint centre;


IplImage *cannyPic = cvCreateImage(cvGetSize(testPic), testPic->depth, 1);
cvCanny(testPic, cannyPic, 50, 150, 3);


//寻找Y坐标
yTop = yDown = 0;
for(i=0; i<cannyPic->height; i++)
{
yPixelNum = 0;
for(j=0; j<cannyPic->width; j++)
{
scalar = cvGet2D(cannyPic, i, j);


if(scalar.val[0] == 255)
yPixelNum++;


}


if(yPixelNum>=2 && flag == 0)
{
yTop = i;
flag = 1;
}


if(flag == 1 && yPixelNum<2)
{
yDown = i;
flag = 0;


if((yDown-yTop)<5)
yDown = yTop = 1;


else
letterHeight = yDown-yTop;


}


}




int k, x, y, m, n;
CvScalar ROIScalar;


//寻找x坐标
k=0;
flag = 0;
xLeft = xRight = 0;
for(i=0; i<cannyPic->width; i++)
{
xPixelNum = 0;
for(j=yTop; j<=yDown; j++)
{
scalar = cvGet2D(cannyPic, j, i);


if(scalar.val[0]==255)
xPixelNum++;
}


if(flag==0 && xPixelNum>=2)
{
xLeft = i;
flag = 1;
}


if(flag==1 && xPixelNum<2)
{
xRight = i;
flag = 0;


if((xRight-xLeft)<3)
xLeft = xRight = 1;


else
{
double testVector[dimNum] = {0};
double tempWidth;
tempWidth = xRight-xLeft;
centre.x = xLeft+tempWidth/2;
centre.y = yTop+letterHeight/2;


letterWidth = letterHeight;


IplImage *ROIPic = cvCreateImage(cvSize(letterHeight, letterWidth), cannyPic->depth, cannyPic->nChannels);
cvSetImageROI(cannyPic, cvRect(centre.x-letterWidth/2, yTop, letterHeight, letterWidth));
cvCopyImage(cannyPic, ROIPic);
cvResetImageROI(cannyPic);


//八个方向向量
//左边
for(x=0; x<ROIPic->width; x++)
{
ROIScalar = cvGet2D(ROIPic, ROIPic->height/2, x);
if(ROIScalar.val[0]==255)
{
testVector[0] = x;
break;
}
}
//右边
for(x=ROIPic->width-1; x>=0; x--)
{
ROIScalar = cvGet2D(ROIPic, ROIPic->height/2, x);
if(ROIScalar.val[0]==255)
{
testVector[1] = ROIPic->width-x;
break;
}
}
//上边
for(y=0; y<ROIPic->height; y++)
{
ROIScalar = cvGet2D(ROIPic, y, ROIPic->width/2);
if(ROIScalar.val[0]==255)
{
testVector[2] = x;
break;
}
}
//下边
for(y=ROIPic->height-1; y>=0; y--)
{
ROIScalar = cvGet2D(ROIPic, y, ROIPic->width/2);
if(ROIScalar.val[0]==255)
{
testVector[3] = ROIPic->height-x;
break;
}
}
//左上
for(x=0; x<ROIPic->width; x++)
{
ROIScalar = cvGet2D(ROIPic, x, x);
if(ROIScalar.val[0]==255)
{
testVector[4] = sqrtf(2*x*x);
break;
}
}
//右下
for(x=ROIPic->width-1, y=ROIPic->height-1; x>=0 && y>=0; y--,x--)
{
ROIScalar = cvGet2D(ROIPic, y, x);
if(ROIScalar.val[0]==255)
{
testVector[5] = sqrtf((ROIPic->height-y)*(ROIPic->height-y)+(ROIPic->width-x)*(ROIPic->width-x));
break;
}
}
//右上
for(x=ROIPic->width-1, y=0; x>=0 && y<ROIPic->height; y++,x--)
{
ROIScalar = cvGet2D(ROIPic, y, x);
if(ROIScalar.val[0]==255)
{
testVector[6] = sqrtf(2*y*y);
break;
}
}
//左下
for(x=0, y=ROIPic->height-1; x<ROIPic->width; y--,x++)
{
ROIScalar = cvGet2D(ROIPic, y, x);
if(ROIScalar.val[0]==255)
{
testVector[7] = sqrtf(2*x*x);
break;
}
}

//生成模糊向量
double maxDis;
maxDis = testVector[0];


//寻找最大距离
for (m=1; m<dimNum; m++)
if(maxDis<testVector[m])
maxDis = testVector[m];


//模糊化
for(m=0; m<dimNum; m++)
testVector[m] = testVector[m]/maxDis;


//计算贴进度
fuzzyNearness(testVector);


}
}
}








}




//获取26个字母的迷糊向量
void getFuzzyVector(IplImage *srcPic)
{
int i, j;
int flag = 0;


CvScalar scalar;
int xPixelNum, yPixelNum;
int yTop, yDown, xLeft, xRight;
int letterHeight, letterWidth;
CvPoint centre;


IplImage *cannyPic = cvCreateImage(cvGetSize(srcPic), srcPic->depth, 1);
cvCanny(srcPic, cannyPic, 50, 150, 3);


//寻找Y坐标
yTop = yDown = 0;
for(i=0; i<cannyPic->height; i++)
{
yPixelNum = 0;
for(j=0; j<cannyPic->width; j++)
{
scalar = cvGet2D(cannyPic, i, j);


if(scalar.val[0] == 255)
yPixelNum++;


}


if(yPixelNum>=20 && flag == 0)
{
yTop = i;
flag = 1;
}


if(flag == 1 && yPixelNum<20)
{
yDown = i;
flag = 0;

if((yDown-yTop)<8)
yDown = yTop = 1;


else
letterHeight = yDown-yTop;


}

}




int k, x, y, m, n;
CvScalar ROIScalar;


//寻找x坐标
k=0;
flag = 0;
xLeft = xRight = 0;
for(i=0; i<cannyPic->width; i++)
{
xPixelNum = 0;
for(j=yTop; j<=yDown; j++)
{
scalar = cvGet2D(cannyPic, j, i);


if(scalar.val[0]==255)
xPixelNum++;
}


if(flag==0 && xPixelNum>=2)
{
xLeft = i;
flag = 1;
}


if(flag==1 && xPixelNum<2)
{
xRight = i;
flag = 0;


if((xRight-xLeft)<3)
xLeft = xRight = 1;


else
{
double tempWidth;
tempWidth = xRight-xLeft;
centre.x = xLeft+tempWidth/2;
centre.y = yTop+letterHeight/2;


letterWidth = letterHeight;


IplImage *ROIPic = cvCreateImage(cvSize(letterHeight, letterWidth), cannyPic->depth, cannyPic->nChannels);
cvSetImageROI(cannyPic, cvRect(centre.x-letterWidth/2, yTop, letterHeight, letterWidth));
cvCopyImage(cannyPic, ROIPic);
cvResetImageROI(cannyPic);


//八个方向向量
//左边
for(x=0; x<ROIPic->width; x++)
{
  ROIScalar = cvGet2D(ROIPic, ROIPic->height/2, x);
if(ROIScalar.val[0]==255)
{
letterVector[k][0] = x;
break;
}
}
//右边
for(x=ROIPic->width-1; x>=0; x--)
{
ROIScalar = cvGet2D(ROIPic, ROIPic->height/2, x);
if(ROIScalar.val[0]==255)
{
letterVector[k][1] = ROIPic->width-x;
break;
}
}
//上边
for(y=0; y<ROIPic->height; y++)
{
ROIScalar = cvGet2D(ROIPic, y, ROIPic->width/2);
if(ROIScalar.val[0]==255)
{
letterVector[k][2] = x;
break;
}
}
//下边
for(y=ROIPic->height-1; y>=0; y--)
{
ROIScalar = cvGet2D(ROIPic, y, ROIPic->width/2);
if(ROIScalar.val[0]==255)
{
letterVector[k][3] = ROIPic->height-x;
break;
}
}
//左上
for(x=0; x<ROIPic->width; x++)
{
ROIScalar = cvGet2D(ROIPic, x, x);
if(ROIScalar.val[0]==255)
{
letterVector[k][4] = sqrtf(2*x*x);
break;
}
}
//右下
for(x=ROIPic->width-1, y=ROIPic->height-1; x>=0 && y>=0; y--,x--)
{
ROIScalar = cvGet2D(ROIPic, y, x);
if(ROIScalar.val[0]==255)
{
letterVector[k][5] = sqrtf((ROIPic->height-y)*(ROIPic->height-y)+(ROIPic->width-x)*(ROIPic->width-x));
break;
}
}
//右上
for(x=ROIPic->width-1, y=0; x>=0 && y<ROIPic->height; y++,x--)
{
ROIScalar = cvGet2D(ROIPic, y, x);
if(ROIScalar.val[0]==255)
{
letterVector[k][6] = sqrtf(2*y*y);
break;
}
}
//左下
for(x=0, y=ROIPic->height-1; x<ROIPic->width; y--,x++)
{
ROIScalar = cvGet2D(ROIPic, y, x);
if(ROIScalar.val[0]==255)
{
letterVector[k][7] = sqrtf(2*x*x);
break;
}
}


k++;

}
}
}


letterSize.height = letterHeight;
letterSize.width = letterWidth;


//生成模糊向量
double maxDis;
for(i=0; i<N; i++)
{
maxDis = letterVector[i][0];


//寻找最大距离
for (j=1; j<dimNum; j++)
if(maxDis<letterVector[i][j])
maxDis = letterVector[i][j];


//模糊化
for(j=0; j<dimNum; j++)
letterVector[i][j] = letterVector[i][j]/maxDis;


}


}


运行结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值