请问关于验证的识别的有关问题-

请教关于验证的识别的问题-------------高手请进!!!
本帖最后由 cowbo 于 2014-09-21 12:20:21 编辑
纯技术研究
小弟最近在研究验证识别,发现网络上很多都是要分割字符的,达不到要求.
我想解决连体的问题,假设图片是没有旋转的,有连体.

但我的代码发现有一些问题,
无法对变体文字进行处理,也就是"验证码大图片"比"模版图片"多一个或少一个像素点时,会出现问题.

我现在的思路是这样:
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; //开始计数
    //扫描整个小图