首先将位图分成同样大小的小块,求出每一块灰度的平均值,然后和每个字符的灰度做比较,找出最接近的那个字符,来代表这一小块图象。
字符的灰度和它所占的黑色点数有关,点越少,灰度值越大,空格字符的灰度最大,为全白,因为它一个黑点也没有
每个字符的面积是8×16(宽×高),所以一个字符的灰度值可以用如下的公式计算(1-所占的黑点数/(8×16))×255
#include "cv.h"
#include "highgui.h"
using namespace cv;
#define PI 3.1415926
#define RADIAN(angle) ((angle)*PI/180.0)
static char ch[95]={' ','`','1','2','3','4','5','6','7','8','9','0','-','=','\\',
'q','w','e','r','t','y','u','i','o','p','[',']',
'a','s','d','f','g','h','j','k','l',';','\'',
'z','x','c','v','b','n','m',',','.','/',
'~','!','@','#','$','%','^','&','*','(',')','_','+','|',
'Q','W','E','R','T','Y','U','I','O','P','{','}',
'A','S','D','F','G','H','J','K','L',':','"',
'Z','X','C','V','B','N','M','<','>','?'};
static int gr[95]={0,7,22,28,31,31,27,32,22,38,32,40, 6,12,20,38,32,26,20,24,40,
29,24,28,38,32,32,26,22,34,24,44,33,32,32,24,16, 6,22,26,22,
26,34,29,35,10, 6,20,14,22,47,42,34,40,10,35,21,22,22,16,14,
26,40,39,29,38,22,28,36,22,36,30,22,22,36,26,36,25,34,38,24,
36,22,12,12,26,30,30,34,39,42,41,18,18,22};
void Image2txt(Mat& mat)
{
int M=mat.rows;
int N=mat.cols;
//将字符按灰度值排序
for(int i=0;i<94;i++)
for(int j=i+1;j<95;j++)
if(gr[i]>gr[j])
{
char tchar=ch[i];
ch[i]=ch[j];
ch[j]=tchar;
int tint=gr[i];
gr[i]=gr[j];
gr[j]=tint;
}
int transWidth=N/8;
int transHeight=M/16;
FILE* fp;
if((fp=fopen("a.txt","w"))==NULL)
exit(0);
for(int i=0;i<transHeight;i++)
{
for(int j=0;j<transWidth;j++)
{
int grayIndex=0;
//计算16*8方块的平均灰度值
for(int i1=0;i1<16;i1++)
{
for(int j1=0;j1<8;j1++)
{
grayIndex+=(int)(255-mat.ptr<uchar>(i*16+i1)[j*8+j1]);
}
}
grayIndex/=(16*8);
grayIndex=gr[94]*grayIndex/255;//拉伸
//寻找字符
int k=0;
while(gr[k+1]<grayIndex)
k++;
fputc(ch[k],fp);
}
fputc(13,fp);
fputc(10,fp);
}
fclose(fp);
}
int main()
{
//读取图像
Mat image;
image=imread("circle.jpg",CV_LOAD_IMAGE_GRAYSCALE);
int M=image.rows;
int N=image.cols;
Image2txt(image);
cvNamedWindow("test",CV_WINDOW_AUTOSIZE);
imshow("test",image);
waitKey(0);
return 0;
}