tesseract识别图片中文字(一)

时间:2022-01-13 23:27:59
 

  一、对于复杂背景中的文本提取

 我测试用的简单的单行文本,如果非文本区多对二值化影响大,首先进行提取文本行,再对提取的文本行进行二值化。

实例图片:

tesseract识别图片中文字(一)

图片中的文字区域从此视频帧中提取:

tesseract识别图片中文字(一)

1、切取图片中的行

      提取边缘信息,边缘图像进行水平投影,将每一行中的像素值相加,得到一个每行边缘信息的数组,

求数组的波谷,两个波谷直接的区间就为文本行。

     求取波谷,我也没想到什么好的算法,因为数组是有波动的,只提取极小值也不对,会提取到特别多个波谷。

 下一步想平滑后求极小值。

目前切行后为:

tesseract识别图片中文字(一)

 

2、对文本行归一化到一定的高

      按原来的宽高比对图片进行缩放,缩放到高为80个像素点(看论文里的经验值),便于文本的识别。

 

        float ratioWH = (float)(image->width)/image->height;
	CvSize cv;
	cv.height = 80;//将文字行比例转换为高80
	cv.width = 80*ratioWH;
	IplImage *norImage = cvCreateImage(cv,8,1);
	cvResize(image,norImage);

3、对归一化的文本行进行二值化

      提取归一化文本行的边缘信息,因为文本现在占图像的主体,边缘点的特征跟文本的特征比较相似(对于渐变文本,边缘和

填充不一致的也没有考虑,只考虑简单的文本颜色比较单调的),根据边缘点的位置在归一化图上提取相应点的颜色特征,

在这里我又加了连通域分析,不过感觉没有什么改变。

        IplImage *cannyImage = cvCreateImage(cvGetSize(norImage),8,1);
	cvCanny(norImage,cannyImage,50,150);
	CvMemStorage *pStor = cvCreateMemStorage(0);///创建目标轮廓存储空间;
	CvSeq        *pCont = NULL;///无需释放内存
	cvFindContours(cannyImage, pStor, &pCont,sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);//获取二值图像轮廓信息
	cvDrawContours(cannyImage,pCont,cvScalarAll(255),cvScalarAll(255),0,CV_FILLED,8, cvPoint(0, 0));
         int sum = 0;
	int num = 0;
	for(int i=0;i<norImage->height;i++){
		for(int j=0;j<norImage->width;j++){
			uchar data = *(cannyImage->imageData+i*cannyImage->widthStep+j);
			if(data!=0){
				uchar data2 = *(norImage->imageData+i*norImage->widthStep+j);
				sum += data2;
				num++;
			}
		}
	}
	//二值化
	float average =(float)(sum)/num;
	for(int i=0;i<norImage->height;i++){
		for(int j=0;j<norImage->width;j++){
			if((uchar)*(norImage->imageData+i*norImage->widthStep+j)>average){
				*(norImage->imageData+i*norImage->widthStep+j) = 255;
			}else{
				*(norImage->imageData+i*norImage->widthStep+j) = 0;
			}
		}
	}


二值化后图片:

tesseract识别图片中文字(一)

 

背景还是有没有去掉的,根据上视频帧是曝光的原因,考虑均衡一下。

4、然后用二值化的图片再用tesseract识别。

http://blog.csdn.net/kuaile123/article/details/9302949