C++ 借助 Tesseract-OCR 识别乐讯新版验证码

首先看看新版验证码, 

            

嗯,难度系数设计一般(毕竟是手机站嘛),字符些许偏转、部分稍微扭曲,但没有粘连且位置固定,噪音也比较单一,没有干扰线,正好拿来练练爪.本文演示的仅仅是运用OCR(好处是你不用自己去写匹配算法,缺点是训练过程略繁琐)进行简单的验证码识别,属基础中的基础级别.

原图是JPEG格式, 为了方便在C++操作最好先转成BMP,可以用ConvertJpegToBmp方法进行转换,可自行百度,这里使用专门用于C++处理验证码的辅助类:XYCode来处理这些琐碎的工作.

XYCode verify_code(T("1.jpeg"));
//XYCode verify_code(T("http://blog.csdn.net/rrrfff/1.jpeg"));
实际情况下从网络下载得到的验证码的类型是随机变化的,其中新版的尺寸固定为116x54,所以要判断一下宽度滤去.
if(!(verify_code.InfoHeader.biWidth == 116 && verify_code.InfoHeader.biHeight == 54)) return;

确定是我们要处理的验证码后,在交给OCR前,需要进行一些预处理,这关系到能否识别成功. 我的惯常做法是先截掉多余部分(去掉没用的字符不然会干扰识别),然后去噪(把不需要的信息除去,这里BZ(博主)偷了懒,用的算法比较粗糙,所以有些锯齿,但是影响不太就算了:用ps取得若干个噪点rgb值,确定范围,此范围外的认为是字符,否则统统枪毙):

                //干掉底部19行, 顶部8行
		verify_code.VTrim(8, 19);
		//干掉左边8列
		verify_code.HTrim(4 * 2);
		//简单去噪
		verify_code.ChangePixel(215, 40, 255, 215, 40, 255, 205, 52, 255);

              

然后是二值化(顾名思义,把图像转换成仅有1和0的二进制点阵,其中字符和背景的值是相对的),
for (int h = 0; h < verify_code.InfoHeader.biHeight; ++h)
		{
			XYCode::Pixel *pp = (XYCode::Pixel *)&verify_code.pImageData[verify_code.LineByte * h];
			for (int w = 0; w < verify_code.InfoHeader.biWidth; ++w)
			{
				if ( !(XYCode::is_in(pp[w].r, 250, 5) && XYCode::is_in(pp[w].g, 250, 5)
					&& XYCode::is_in(pp[w].b, 250, 5)) )
				{
					pp[w].r = pp[w].g = pp[w].b = 0;
				} //if
			} //for
		} //for

嗯,看看效果?

            

看起来好多了,就这样,接下来是字符矫正(不太喜欢灰度化,留着先)

首先你需要下载 Tesseract-OCR 3.0.2 VS2010可直接编译源码 jTessBoxEditor-1.0.zip(训练用)

你可能感兴趣的:(C++ 借助 Tesseract-OCR 识别乐讯新版验证码)