请问关于验证的识别的有关问题-
请教关于验证的识别的问题-------------高手请进!!!
纯技术研究
小弟最近在研究验证识别,发现网络上很多都是要分割字符的,达不到要求.
我想解决连体的问题,假设图片是没有旋转的,有连体.
但我的代码发现有一些问题,
无法对变体文字进行处理,也就是"验证码大图片"比"模版图片"多一个或少一个像素点时,会出现问题.
我现在的思路是这样:
0.二值化图片.
1.建立模版文件,把文本切出来另存成一个独立的bmp
2.扫描整个大图,到达每一个像素点时,对比整个小图,看小图是否匹配.
3.把得到的坐标取出来,存入数组,然后取现.
***为了解决变体的问题,我把验证码图进行膨胀处理,这样就抵消掉变体.然后生成的模版图片,把这个图片的像素点中黑色的
模版文件文件夹:把一种验证码的所有图片样本放在一起,文件名格式例如为:a_20.bmp,a表示这个图片是a,而20表示这个图片里黑色的像素点数量.
验证码图:做二值化,降噪,膨胀处理,
但是我的代码运行后,发现出来的结果很乱,在一些验证图样本中,因为会出现几个模版文字出现在一个位置上,比如I和L,V和W...等,
感觉我的代码也有问题,无法处理很多重复...怎么办?
全部代码如下,请高人帮看看如何改才能解决问题,谢了.
main.pas
纯技术研究
小弟最近在研究验证识别,发现网络上很多都是要分割字符的,达不到要求.
我想解决连体的问题,假设图片是没有旋转的,有连体.
但我的代码发现有一些问题,
无法对变体文字进行处理,也就是"验证码大图片"比"模版图片"多一个或少一个像素点时,会出现问题.
我现在的思路是这样:
0.二值化图片.
1.建立模版文件,把文本切出来另存成一个独立的bmp
2.扫描整个大图,到达每一个像素点时,对比整个小图,看小图是否匹配.
3.把得到的坐标取出来,存入数组,然后取现.
***为了解决变体的问题,我把验证码图进行膨胀处理,这样就抵消掉变体.然后生成的模版图片,把这个图片的像素点中黑色的
模版文件文件夹:把一种验证码的所有图片样本放在一起,文件名格式例如为:a_20.bmp,a表示这个图片是a,而20表示这个图片里黑色的像素点数量.
验证码图:做二值化,降噪,膨胀处理,
但是我的代码运行后,发现出来的结果很乱,在一些验证图样本中,因为会出现几个模版文字出现在一个位置上,比如I和L,V和W...等,
感觉我的代码也有问题,无法处理很多重复...怎么办?
全部代码如下,请高人帮看看如何改才能解决问题,谢了.
main.pas
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, ExtDlgs, IdGlobal, Buttons;
const
PixelCountMax = 32768;
type
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
type
TMainForm = class(TForm)
Image1: TImage;
Image2: TImage;
Memo1: TMemo;
Button1: TButton;
OpenPictureDialog1: TOpenPictureDialog;
OpenPictureDialog2: TOpenPictureDialog;
Label1: TLabel;
Memo2: TMemo;
Edit1: TEdit;
Button4: TButton;
procedure Image1Click(Sender: TObject);
procedure Image2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
function BmpCmpEx(bmpBig, bmp: TBitmap; x, y: integer; nV: byte): boolean; //图片对比
function BmpFindEx(bmpBig, bmp: TBitmap; x1, y1, x2, y2: integer; nV: byte; Txt: string): Boolean;
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
//L, T, Lx: Integer; //已找到的子图的x和Y值 ,也就是左边和上边
bmpFindX, bmpFindY: Integer; //第二种方法找到的点
TxtAry: array of string;
eight: array[1..8, 1..8] of TLabel;
CurBmpFname, LastBmpFname: string; //记录当前的小图文件名
implementation
uses StrUtils;
{$R *.dfm}
procedure TMainForm.Image1Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
end;
procedure TMainForm.Image2Click(Sender: TObject);
begin
if OpenPictureDialog2.Execute then
Image2.Picture.LoadFromFile(OpenPictureDialog2.FileName);
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
DoubleBuffered := True;
Image1.Picture.Bitmap.PixelFormat := pf24bit;
Image2.Picture.Bitmap.PixelFormat := pf24bit;
Memo1.Lines.LoadFromFile('C:\ocrlog.txt');
end;
// 模糊判断,在验证图里的(x,y)位置上是不是小图?
// 其中nV是R,G,B的偏差值,0..255
function TMainForm.BmpCmpEx(bmpBig, bmp: TBitmap; x, y: integer; nV: byte): boolean;
var
i, j: integer;
row1, row2: pRGBTripleArray;
p1, p2: TRGBTriple;
pLow, pHigh: TRGBTriple;
{容错加入,当超过一定错误机率时,放弃,否则视为相同}
rate: Double; //容错率,即占小图总像素点的比例
v, k: Integer; //v定义可容错的像索点的数量, k为已错的计算器
begin
result := true;
rate := 0.08; //10%的容错率
v := Trunc((bmp.Width * bmp.Height) * rate); //得出容错的像索点数量
k := 0; //开始计数
//扫描整个小图