太厉害了,学习ING 图像识别还未涉及

解决方案 »

  1.   

    代码很搓,就是实验,Delphi我也不是很熟。
    (一) 去干扰线
    首先,验证码图片是这样子的,28像素高。100像素宽,有干扰线(还与文字同色的),干扰点。随机颜色,随机旋转角度
    首先,我尝试去干扰线,通过函数的形式计算破坏红色数字的完整性,我采用遍历单列,如果列里有只有2个红色像素点的话,就变成白色去除红色 判断颜色我使用的是RGB中R的值大于153,就是包括暗红
    procedure TForm1.GRedLineBMP(BMP:TBITMAP);
    var
    i,j,x,y,co,n:integer;
    p: PByteArray;
    begin
    Bmp.PixelFormat := pf24Bit;
    randomize;
    for i := 0 to BMP.Width - 1 do
    begin
    for j := 0 to BMP.Height - 1 do
    begin
    p := Bmp.scanline[j];
    if p[i * 3+2]>=153 then //如果红色值大于153
    begin
    co:=0;
    for n := 0 to BMP.Height - 1 do
    begin
    if Colorflag(BMP.Canvas.Pixels[i, n]) =1 then
    begin
    co:=co+1;
    end;
    end;
    if(co<=2) then
    BMP.Canvas.Pixels[i, j] := clwhite
    else
    begin
    end;
    end;
    end;
    end;
    end;
    效果是这样的
    因为我发现随机噪点颜色是固定的,我就提前把噪点颜色给clwhite了
    后面这个是因为随机干扰线在文字上方,就不处理了,应该不会有太大影响吧。
      

  2.   

    (二)图像二色化处理
    就是把彩色的图片变成黑白的图片,好识别
    采用的那个标准的灰度计算公式
    procedure TForm1.BWBMP(BMP:TBITMAP);
    var
    x,y,gray:Integer;
    p: PByteArray;
    begin
    Bmp.PixelFormat := pf24Bit;
    randomize;
    for y := 0 to BMP.Height - 1 do
    begin
    p := Bmp.scanline[y];
    for x := 0 to BMP.Width - 1 do
    begin
    // Gray := Round((p[x * 3 + 2] + p[x * 3 + 1]+ p[x * 3])/3);
    Gray := Round(p[x * 3 + 2] * 0.3 + p[x * 3 + 1] * 0.59 + p[x
    * 3] * 0.11);
    if gray > 150 then //全局阀值128
    begin
    p[x * 3] := 255;
    p[x * 3 + 1] := 255;
    p[x * 3 + 2] := 255;
    end
    else
    begin
    p[x * 3] := 0;
    p[x * 3 + 1] := 0;
    p[x * 3 + 2] := 0;
    end;
    end;
    end;
    end;
    注释部分是RGB平均值分法,我也不知道哪个好一些
    变成黑白后,又补洞修复了一下
    //补洞
    procedure TForm1.BDBMP(BMP1:TBITMAP);
    var
    i,j:Integer;
    begin
    //补洞
    for i := 0 to BMP1.Width - 1 do
    begin
    for j := 0 to BMP1.Height - 1 do
    begin
    if BMP1.Canvas.Pixels[i, j]=$ffffff then
    begin
    if ColorBlackflag(BMP1.Canvas.Pixels[i+1, j])+ ColorBlackflag(BMP1.Canvas.Pixels[i-1, j])
    +ColorBlackflag(BMP1.Canvas.Pixels[i, j-1])+ColorBlackflag(BMP1.Canvas.Pixels[i, j+1])=4 then
    begin
    BMP1.Canvas.Pixels[i, j]:= clblack;
    end;
    end;
    end;
    end;end;
    就是判断当前白像素点的上下左右是不是全是黑色的,如果是黑的,那就把当前的变成黑的
    效果如下
      

  3.   

    (三)然后就该分割了,我这个大概是位移5个像素,每15个像素为一个数字,具体分割我用的
    BitBlt(bits[i].Canvas.Handle, 0, 0, 15, 28, BMP.Canvas.Handle, 5+i*15, 0, SRCCOPY);
    具体代码不上了,我写的太烂,我都不知道会不会内存泄露,就不误导了。
      

  4.   

    (四)图片旋转,这个我查了一些别人写的经验,好像用X轴投影法,就是把所有有黑色像素点的X轴标记出来,投影到下面成为一条线,计算线长度。然后对图片进行旋转。最短的线就是正立的,当然有些也不是正立的
    //计算投影长度
    function TForm1.LENGBMP(BMP: TBITMAP):Integer;
    var
    x,y,i,len:Integer;
    xarray:array[0..14] of Integer;
    begin
    len:=0;
    for i := 0 to BMP.Width-1 do
    xarray[i] := 0;
    for y := 0 to BMP.Height - 1 do
    begin
    for x := 0 to BMP.Width-1 do
    begin
    if BMP.Canvas.Pixels[x, y]= clblack then
    xarray[x]:=xarray[x]+1;
    end;
    end;
    for i := 0 to BMP.Width-1 do
    if xarray[i] >0 then 
    begin
    len :=len+1;
    end;
    result:=len;
    end;
      

  5.   

    (五) 图片旋转
    //获得旋转角度的BMP
    // x,y:质心坐标数组
    //angle 旋转角度
    //x2,y2 新坐标点
    // x2=(x - x1) * Cos(angle * 3.14 / 180) - (y - y1) * Sin(angle * 3.14 / 180) + x1
    // y2=(y - y1) * Cos(angle * 3.14 / 180) + (x - x1) * Sin(angle * 3.14 / 180) + y1
    通过正负30度旋转,就变成了这个挫样