Ис нова об распознавании картинок

Discussion in 'Уязвимости' started by Mirovan, 18 Jan 2007.

  1. Mirovan

    Mirovan Elder - Старейшина

    Joined:
    10 Apr 2005
    Messages:
    49
    Likes Received:
    0
    Reputations:
    0
    Тема была затронута не раз. Но всё же.

    Есть изображение: на странице http://l2top.ru/?voteme=1139&rating=full , требуется (как сбственно вы и догадались) распознать эту картинку.

    При взгляде на это изображение срузу понятно что нет никакой защиты от распознавания - фон достаточно отличается от цвета цифр, цифры всегда имеют иди и тот же шрифт , размер и располагаются строго по центру.

    Какой алгоритм здесь подойдет - распознавание по байтам или распознавание по шаблону (если кто знает четкий алгоритм скажите) ?
     
  2. Mirovan

    Mirovan Elder - Старейшина

    Joined:
    10 Apr 2005
    Messages:
    49
    Likes Received:
    0
    Reputations:
    0
    Начал писать код на пасе (делфи), возникла проблемка:

    загружаю картинку со страницы http://l2top.ru/?voteme=1139&rating=full , сохраняю файлик как ЖПГ, открываю в mspaint, сохраняю как монохромный, плучается здорово !

    Попытался реализовать аналогичное на делфи - не катит, получается все равно 24 бита:

    function JPEG2BMP(const JPGFile, BMPFile: string): boolean;
    var
    JPG: TJPEGImage;
    BMP: TBitmap;
    begin
    JPG:= TJPEGImage.Create;
    BMP:= TBitmap.Create;
    try
    JPG.LoadFromFile(JPGFile);
    BMP.PixelFormat:= pf1bit;
    BMP.Assign(JPG);
    BMP.SaveToFile(BMPFile);
    finally
    FreeAndNil(JPG);
    FreeAndNil(BMP);
    Result:= FileExists(BMPFile);
    end;
    end;
     
  3. zl0ba

    zl0ba ПсихолоГ

    Joined:
    10 Oct 2006
    Messages:
    393
    Likes Received:
    301
    Reputations:
    52
    Наверно не в той ветке создал эту тему. С формулируй вопрос правильней!
     
  4. ZaCo

    ZaCo Banned

    Joined:
    20 Jun 2005
    Messages:
    737
    Likes Received:
    336
    Reputations:
    215
    тут достаточно определить цвет цифр, а так цифры всегда стоят на одних и тех же местах просто берем точку с нужной координатой. но тут возможно наложении на нее шума, поэтому берем область одной из цифр размерами 5х5 и находим тот цвет который встречается чаще - это и будет искомый. делаем с этого всего битовую матрицу - 1-пиксель принадлежит цифре, 0 - не принадлежит. сравниваем количество точек при совмещении. все.
     
  5. Mirovan

    Mirovan Elder - Старейшина

    Joined:
    10 Apr 2005
    Messages:
    49
    Likes Received:
    0
    Reputations:
    0
    Может быть проще сравнивать по заранее готовому шаблону ? Именно так я и хочу сделать, т.е. у меня имеются 10 файлов с готовыми шаблонами цифр - от 0 до 9, такого же размера как и на примере картинки и четко черно-белого цвета, далее просто дело прямых рук написания кода для сравнения, с этим у меня проблем, думаю не будет.

    Но вот проблемка в преобразовании цветной картинки JPeG в черно-белую BMP (код см. выше), не могу понять почему не работат, думаю что компонент делфи как то кривовато работает, может есть другой способ?
     
  6. Mirovan

    Mirovan Elder - Старейшина

    Joined:
    10 Apr 2005
    Messages:
    49
    Likes Received:
    0
    Reputations:
    0
    Вобщем с изобрадением я разобрался, вот код:


    function setBWColor(c: TColor): TColor;
    begin
    if c > (255*255*255)/2
    then c := clWhite
    else c := clBlack;
    Result := c;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    h, w: Integer;
    begin
    for w := 0 to Image1.Width-1 do
    for h := 0 to Image1.Height-1 do
    Image1.Canvas.Pixels[w,h] := setBWColor(Image1.Canvas.Pixels[w,h]);
    end;


    В результате из BMP-шной картинки получается монохромное изображение. Теперь задача его раскодировать
     
  7. Abra

    Abra Member

    Joined:
    17 Sep 2005
    Messages:
    278
    Likes Received:
    51
    Reputations:
    29
    ))))))))))))
    непредвиденное обстоятельство, да?))
     
  8. Mirovan

    Mirovan Elder - Старейшина

    Joined:
    10 Apr 2005
    Messages:
    49
    Likes Received:
    0
    Reputations:
    0
    Ну, вобщем приложение готово, работает по шаблону, всё очень просто

    вот код

    Code:
    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls, jpeg, ExtDlgs;
    
    type
      TForm1 = class(TForm)
        Image1: TImage;
        Button1: TButton;
        OpenPictureDialog1: TOpenPictureDialog;
        Edit1: TEdit;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
      TMas = array[1..210, 1..65] of Boolean;
    
    var
      Form1: TForm1;
      Mas: TMas;
      dir: String;
    
    implementation
    
    {$R *.dfm}
    
    function JPEG2BMP(const JPGFile, BMPFile: string): boolean;
    // Ôóíêöèÿ äëÿ êîíâåðòèðîâàíèÿ JPEG ôàéëà â <BMP>
    // JPGFile - èìÿ îòêðûâàåìîãî ôàéëà
    // BMPFile - èìÿ <ñîõðàíÿåìîãî> ôàéëà
    var
      JPG: TJPEGImage;
      BMP: TBitmap;
    begin
      JPG := TJPEGImage.Create;
      BMP := TBitmap.Create;
      try
        JPG.LoadFromFile(JPGFile);
        BMP.PixelFormat:= pf1bit;
        BMP.Assign(JPG);
        BMP.SaveToFile(BMPFile);
      finally
        FreeAndNil(JPG);
        FreeAndNil(BMP);
        Result := FileExists(BMPFile);
      end;
    end;
    
    
    function setBWColor(c: TColor): TColor;
    begin
      if c > (255*255*255)/2
        then c := clWhite
        else c := clBlack;
      Result := c;
    end;
    
    
    function encodeImg(Mas: TMas): String;
    type
      Tfiles = array[0..9] of String;
    var
      f: Tfiles;
      i, j, k: Integer;
      shablon: array[1..32, 1..12] of Boolean;
      BMP: TBitmap;
      max, equal: Integer;
      temp, st: String;
    begin
      for i := 0 to 9 do
        f[i] := dir + '/shablon/' + IntToStr(i) + '.bmp';
    
      BMP := TBitmap.Create;
    
      st := '';
    
      max := 0;
    // 1 öèôðà
      for k := 0 to 9 do
        begin
          BMP.LoadFromFile(f[k]);
          for i := 1 to 32 do
            for j := 1 to 12 do
              if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
                then shablon[i,j] := true
                else shablon[i,j] := false;
    
          equal := 0;
          for i := 1 to 32 do
            for j := 1 to 12 do
              begin
                if shablon[i,j] = Mas[i+27,j+16] then equal := equal + 1;
              end;
          if (equal > max) then
            begin
              max := equal;
              temp := IntToStr(k);
            end;
        end;
      st := st + temp;
    
      max := 0;
    // 2 öèôðà
      for k := 0 to 9 do
        begin
          BMP.LoadFromFile(f[k]);
          for i := 1 to 32 do
            for j := 1 to 12 do
              if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
                then shablon[i,j] := true
                else shablon[i,j] := false;
    
          equal := 0;
          for i := 1 to 32 do
            for j := 1 to 12 do
              begin
                if shablon[i,j] = Mas[i+54,j+16] then equal := equal + 1;
              end;
          if (equal > max) then
            begin
              max := equal;
              temp := IntToStr(k);
            end;
        end;
      st := st + temp;
    
      max := 0;
    // 3 öèôðà
      for k := 0 to 9 do
        begin
          BMP.LoadFromFile(f[k]);
          for i := 1 to 32 do
            for j := 1 to 12 do
              if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
                then shablon[i,j] := true
                else shablon[i,j] := false;
    
          equal := 0;
          for i := 1 to 32 do
            for j := 1 to 12 do
              begin
                if shablon[i,j] = Mas[i+81,j+16] then equal := equal + 1;
              end;
          if (equal > max) then
            begin
              max := equal;
              temp := IntToStr(k);
            end;
        end;
      st := st + temp;
    
      max := 0;
    // 4 öèôðà
      for k := 0 to 9 do
        begin
          BMP.LoadFromFile(f[k]);
          for i := 1 to 32 do
            for j := 1 to 12 do
              if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
                then shablon[i,j] := true
                else shablon[i,j] := false;
    
          equal := 0;
          for i := 1 to 32 do
            for j := 1 to 12 do
              begin
                if shablon[i,j] = Mas[i+108,j+16] then equal := equal + 1;
              end;
          if (equal > max) then
            begin
              max := equal;
              temp := IntToStr(k);
            end;
        end;
      st := st + temp;
    
    
    
      max := 0;
    // 5 öèôðà
      for k := 0 to 9 do
        begin
          BMP.LoadFromFile(f[k]);
          for i := 1 to 32 do
            for j := 1 to 12 do
              if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
                then shablon[i,j] := true
                else shablon[i,j] := false;
    
          equal := 0;
          for i := 1 to 32 do
            for j := 1 to 12 do
              begin
                if shablon[i,j] = Mas[i+135,j+16] then equal := equal + 1;
              end;
          if (equal > max) then
            begin
              max := equal;
              temp := IntToStr(k);
            end;
        end;
      st := st + temp;
    
    
    
      max := 0;
    // 6 öèôðà
      for k := 0 to 9 do
        begin
          BMP.LoadFromFile(f[k]);
          for i := 1 to 32 do
            for j := 1 to 12 do
              if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
                then shablon[i,j] := true
                else shablon[i,j] := false;
    
          equal := 0;
          for i := 1 to 32 do
            for j := 1 to 12 do
              begin
                if shablon[i,j] = Mas[i+162,j+16] then equal := equal + 1;
              end;
          if (equal > max) then
            begin
              max := equal;
              temp := IntToStr(k);
            end;
        end;
      st := st + temp;
    
      Result := st;
    
    end;
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      h, w: Integer;
      Mas: TMas;
    begin
      OpenPictureDialog1.Execute;
      JPEG2BMP(OpenPictureDialog1.FileName, dir+'/temp/temp.bmp');
      Image1.Picture.LoadFromFile(dir+'temp/temp.bmp');
      for w := 0 to Image1.Width-1 do
        for h := 0 to Image1.Height-1 do
          begin
            Image1.Canvas.Pixels[w,h] := setBWColor(Image1.Canvas.Pixels[w,h]);
            if (Image1.Canvas.Pixels[w,h] = clWhite)
              then Mas[w+1, h+1] := true   //áåëûé
              else Mas[w+1, h+1] := false; //÷åðíûé
          end;
      Edit1.Text := encodeImg(Mas);
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      dir := ExtractFilePath(ParamStr(0));
    end;
    
    end.
    

    p.s. работает только для картинки по адресу http://l2top.ru/?voteme=1139&rating=full , но на этой основе можно забадяжить своё :)
     
  9. Mirovan

    Mirovan Elder - Старейшина

    Joined:
    10 Apr 2005
    Messages:
    49
    Likes Received:
    0
    Reputations:
    0
    Уже нет :)
     
  10. nerezus

    nerezus Banned

    Joined:
    12 Aug 2004
    Messages:
    3,191
    Likes Received:
    729
    Reputations:
    266
    А такая красивая функция encodeImg(), аж прямо ужас
     
  11. ZaCo

    ZaCo Banned

    Joined:
    20 Jun 2005
    Messages:
    737
    Likes Received:
    336
    Reputations:
    215
    >>Может быть проще сравнивать по заранее готовому шаблону ?
    как вы будете сравнивать с шаблоном если на изображении "мусор"?
     
  12. Zadoxlik

    Zadoxlik рояль с сыром

    Joined:
    28 Feb 2005
    Messages:
    758
    Likes Received:
    216
    Reputations:
    257
    я так капчу на твоем хомяке сломал :D
     
  13. ZaCo

    ZaCo Banned

    Joined:
    20 Jun 2005
    Messages:
    737
    Likes Received:
    336
    Reputations:
    215
    у меня даже проще, без шума и координатных растяжений\поворотов было :)
     
  14. Zadoxlik

    Zadoxlik рояль с сыром

    Joined:
    28 Feb 2005
    Messages:
    758
    Likes Received:
    216
    Reputations:
    257
    Точно :dddd
     
  15. Mirovan

    Mirovan Elder - Старейшина

    Joined:
    10 Apr 2005
    Messages:
    49
    Likes Received:
    0
    Reputations:
    0
    Выше говорилось что это функция специфична только для данной картинки, поэтому прошу строго не судить о названии функций :)
     
  16. Mirovan

    Mirovan Elder - Старейшина

    Joined:
    10 Apr 2005
    Messages:
    49
    Likes Received:
    0
    Reputations:
    0
    сам шум на этой картинке (http://l2top.ru - выберите сайт нажмите кнопку "мой выбор" чтобы увидеть картинку) представлен в другом цвете, именно поэтому я преобразовываю картинку в монохромный рисунок , что позводяет убрать шум .