OCR'ye Giriş - CAPTCHA Kodların Çözümlenmesi üzerine

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

OCR'ye Giriş - CAPTCHA Kodların Çözümlenmesi üzerine

Mesaj gönderen mrmarman »

Herkese selam.

- Dünyada eskiden beri kullanılan, Türkiye'de de son zamanlarda hızla yaygınlaşan bir sistemle hepimiz bir şekilde tanıştık.

- Türkiye'deki örnekleri ÖSYM Bilgi Sistemi, T.C.Kimlik bilgi sorgulama ve SSK Pirim ödemeleri sorgulama gibi sitelerde biz bilgisayar programcılarının otomasyonunu engellemeyi amaçlayan ama bireysel kullanıcıların bu bilgiden faydalanmasını sağlayan bir sistemi ele alıyoruz.

- Bu makalemizde gerek forumlarda gerekse news grouplarda bana sıkça sorulan bu kodların bilgisayara nasıl okutulabileceği sorusuna açıklık getirmek için, uygulanabilecek tekniklerden OCR (optik karakter tanımlama'nın İngilizcesi Optical Character Recognition) tekniğini irdeliycez.

- Makalede, sadece Captcha kod çözümlemeyi değil, Canvas operasyonlarının nasıl daha etkin kullanılacağını da göreceğiz. :idea:

- Bu sistem için oluşturulan dinamik resimlere CAPTCHA deniyor..
TR Wikipedia yazdı:CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) Carnegie Mellon School of Computer Science tarafından geliştirilen bir projedir. Projenin amacı bilgisayar ile insanların davranışlarının ayırt edilmesidir ve daha çok bu ayrımı yapmanın en zor olduğu web ortamında kullanılmaktadır.

CAPTCHA projesinin bazı uygulamalarına çoğu web sayfalarında rastlamak mümkündür. Üyelik formlarında rasgele resim gösterilerek formu dolduran kişiden bu resmin üzerinde yazan kelimeyi girmesi istenir. Buradaki basit mantık o resimde sadece insan tarafından okunabilecek bir program tarafından okunması zor olan bir kelime oluşturmak. Eğer forma girilen kelime resimdeki ile aynı değilse ya formu dolduran kişi yanlış yaptı ya da formu dolduran bir program önermesini yapabilir.
- Şimdi başlayalım... 8)

- Bir resimdeki karakteri tanımak için aşamalı bazı işlemlerden geçmesi gerekiyor.

- Örnek olarak Türk Telekom ADSL Kota Kullanım Bilgileri sitesi linki olan http://adslkota.ttnet.net.tr/adslkota/login.jsp linkindeki resimli kodları üreten http://adslkota.ttnet.net.tr/adslkota/jcaptcha linkini ele alalım.

Resim
şeklinde kod üretilir. Bunu almanın yollarını forumda irdelemiştik. Ref: viewtopic.php?t=5531#106731

- Bu gördüğünüz kod farklı renklerde ve karakterden oluşan, aynı zamanda karakter sayısı ve yeri sabit olmayan dinamik bir kod resmi.

- Bu resmi işlemek için native olarak tanınan Bitmap formatında alıyoruz.

- İşimizi kolaylaştırmak için ilk olarak bu resmi siyah beyaz formata dönüştürüyoruz. Nasıl mı ? Tabii ki tüm makale boyunca OCR işlemini yapacağımız Canvas operasyonlarıyla...

Kod: Tümünü seç

Procedure SiyahBeyazYap( Image: TImage );
Var
  i,j : Integer;
begin
  With Image.Picture.Bitmap do begin
    PixelFormat := pf4Bit;
    For i := 0 to Width-1 do
      For j := 0 to Height-1 do
        If Canvas.Pixels[i,j]   < clWhite
        then Canvas.Pixels[i,j] := clBlack;
  end;
end;
Resim

- Resmimiz bu hale geldi. Orjinal resme yakından bakacak olursanız, karakterlerin etrafında bozulmalar vardı. Fonksiyonumuzda siyah beyaza dönüştürürken < clWhite diyerek net bir siyat ve net bir beyaz elde ettik. :idea:


- Sıradaki işlem yeri yurdu belli olmayan karakterleri tespit etmek, her birini sınırlarından alıp müstakil basamak resimcikler oluşturmak. Bunun için soldan sağa, yukarıdan aşağıya ve aşağıdan yukarıya döngüler kurarak siyaha rastlaya kadar kırpma işlemi yapacak bir PROCEDURE daha yazıcaz.

Kod: Tümünü seç

Procedure DilimlereAyir( Image:TImage; HedefDizin:String );
Var
  Harf   : TBitmap;
  Hedef  : TFileName;
  i, j,
  Sayac  : Integer;
  oncekison,
  ybas, yson,
  xbas, xson : Integer;
  xGordum : Boolean;
begin
  Harf   := TBitmap.Create;
  Sayac  := 0;
  xBas   := 1;
  xSon   := 1;
  oncekiSon := 0;
  While (xBas > 0) AND ( xSon > 0 ) do begin
    xBas := 0;
    xSon := 0;
    For i := oncekison to Image.Picture.Bitmap.Width do begin
      xGordum := False;
      For j := 0 to Image.Picture.Bitmap.Height do begin
        If Image.Picture.Bitmap.Canvas.Pixels[i,j] = clBlack
        then xGordum := True;
      end;
      If xGordum then begin
         If (xBas = 0) then xBas := i;
      end else begin
         If (xSon = 0) AND (xBas > 0) then xSon := i;
      end;
      If (xBas > 0) AND (xSon > 0) then break;
    end;

    If (xBas > 0) AND (xSon > 0) then begin
      // Üstten Bulalım...
      yBas := 0;
      For j := 0 to Image.Picture.Bitmap.Height do begin
        For i := xBas to xSon do begin
          If Image.Picture.Bitmap.Canvas.Pixels[i,j] = clBlack then
          begin
            yBas := j;
            BreaK;
          end;
        end;
        If yBas > 0 then break;
      end;

      // Alttan Bulalım...
      ySon  := 0;
      For j := Image.Picture.Bitmap.Height downto 0 do begin
        For i := xBas to xSon do begin
          If Image.Picture.Bitmap.Canvas.Pixels[i,j] = clBlack then
          begin
            ySon := j;
            BreaK;
          end;
        end;
        If ySon > 0 then break;
      end;

      Harf.Height := ySon-yBas+1;
      Harf.Width  := xSon-xBas+1;
      Harf.Canvas.CopyRect( Harf.Canvas.ClipRect, Image.Picture.Bitmap.Canvas, Rect(xBas, yBas, xSon, ySon) );
      Inc(Sayac);
      Hedef := Format('%sHarf_%.5d.BMP', [HedefDizin, Sayac]);
      Harf.SaveToFile(Hedef);
      OncekiSon := xSon;
    end;
  end;
  Harf.Free;
end;
- Bu procedure sonucu da aşağıdaki şekilde oluyor...
Resim Resim Resim Resim Resim

- Şimdi elimizde her harfin siyah beyaz hali mevcut. OCR işlemi henüz başlıyor... :o

- OCR işlemi yapılacak sitenin iyi etüd edilmesi gerekmektedir. Ne tip karakterler kullanılıyor, büyük küçük harf kullanımı vb. kriterler üretilmesi sağlanan birden fazla captcha kod incelenerek öğrenilebilir. Bu bize ne sağlar ? Aşağıdaki sorulara cevap bulmamızı ve zamandan tasarruf sağlamamızı sağlar. :wink:

1. Hangi Font tipleri kullanılıyor ? Arial, Times New Roman, vb.
2. Hangi Font stilleri kullanılıyor ? Bold, Italic, her ikisi, vb.
3. BüyükHarf / KüçükHarf Kullanımı ne ölçüde

- Bu soruların cevabına göre fonksiyon döngümüze karar vericez..

Method 1 : ( kendi ürettiğimiz karakterleri karşılaştırma methodu )

- Sorduğumuz sorulara karşılıkilgilendiğimiz ADSL kota sayfası için cevaplar :
1. Font Adı : "Arial" kullanılıyor.
2. Font Stili : [], [Bold], [Italic], [Bold + Italic] yani her dört ihtimalde de bulunabiliyor.
3. Sadece küçük harf kullanılmış.

- Karakterleri bileşenlerine ayırmıştık. Biz program içerisinden Canvas.TextOut ile benzer karakteri üretmeye çalışıcaz. 26 tane ingilizce küçük harfi sırayla canvas üzerine 4 farklı şekil ve boyutta basıcaz.

- Elimizde her karakter için fiziksel büyüklük Width, Height olarak mevcut olduğuna göre her harfi bu sınırlara kadar büyük olacak şekilde (yani Canvas.TextHeight( cHarf ) aynı genişliği bulana kadar Canvas.Font.Size ile oynayarak) deneme yanılma ile karşılaştırmaya hazırlık yapıcaz. Yapılan karşılaştırma sonucu uyumluluk gözlenirse cHarf'dir diyebilicez.


- Elimizdeki ürettiğimiz karakteri de aynı şartlara dönüştürmek için kenar boşluklarını kırpmamız lazım...

- Aşağıdaki fonksiyon, dilimlere ayırmaya benzer ama sadece bir harf için olanıdır. Canvas.Textout ile bastığımız harfin kenarındaki boşlukları kesmek için kullanıcaz...

Kod: Tümünü seç

Procedure BosluklariKirp( Bitmap:TBitmap );
Var
  Harf   : TBitmap;
  i, j   : Integer;
  ybas, yson,
  xbas, xson : Integer;
  xGordum : Boolean;
begin
  Harf   := TBitmap.Create;
  xBas   := 0;
  xSon   := 0;
  // Soldan -> Sağa
  For i := 0 to Bitmap.Width do begin
    xGordum := False;
    For j := 0 to Bitmap.Height do begin
      If Bitmap.Canvas.Pixels[i,j] = clBlack
      then xGordum := True;
    end; // For j
    If xGordum then begin
       If (xBas = 0) then xBas := i;
    end else begin
       If (xSon = 0) AND (xBas > 0) then xSon := i;
    end; // If xGordum
    If (xBas > 0) AND (xSon > 0) then break;
  end; // For i

  If (xBas > 0) AND (xSon > 0) then begin
    // Yulardan  -> Aşağı
    yBas := 0;
    For j := 0 to Bitmap.Height do begin
      For i := xBas to xSon do begin
        If Bitmap.Canvas.Pixels[i,j] = clBlack then
        begin
          yBas := j;
          BreaK;
        end;
      end;
      If yBas > 0 then break;
    end;

    // Alttan -> Yukarı
    ySon  := 0;
    For j := Bitmap.Height downto 0 do begin
      For i := xBas to xSon do begin
        If Bitmap.Canvas.Pixels[i,j] = clBlack then
        begin
          ySon := j;
          BreaK;
        end;
      end;
      If ySon > 0 then break;
    end;

    Harf.Height := ySon-yBas+1;
    Harf.Width  := xSon-xBas+1;
    Harf.Canvas.CopyRect( Harf.Canvas.ClipRect, Bitmap.Canvas, Rect(xBas, yBas, xSon, ySon) );
    Bitmap.Assign(Harf);
  end;
  Harf.Free;
end;
- Şimdi karakterlerine ayırdığımız Captcha kodundaki her harfi karşılaştırıcaz..

- Karşılaştırma Procedure

Kod: Tümünü seç

Procedure Karsilastir(BitmapA, BitmapB: TBitmap;
                      var Alan, Benzer, Fark: Integer);
Type
  TRGB =  Array [WORD] of TRGBTriple;
  pRGBTripleArray =  ^TRGB;
Var
  i, j       :  Integer;
  rowA, rowB :  pRGBTripleArray;
begin
  If (BitmapA.width  = BitmapB.width) and
          (BitmapA.height = BitmapB.height) then begin
    BitmapA.PixelFormat := pf24bit;
    BitmapB.PixelFormat := pf24bit;

    Alan   := BitmapA.width * BitmapA.height;
    Benzer := 0;
    Fark   := 0;

    for j := 0 to BitmapA.height-1 do
    begin
      rowA := BitmapA.Scanline[j];
      rowB := BitmapB.Scanline[j];
      for i := 0 to BitmapA.width-1 do
      begin
          if   (rowA[i].rgbtRed   = rowB[i].rgbtRed)   and
               (rowA[i].rgbtGreen = rowB[i].rgbtGreen) and
               (rowA[i].rgbtBlue  = rowB[i].rgbtBlue)
          then INC(Benzer)
          else INC(Fark)
      end
    end
  end else begin
    Alan   := BitmapA.width * BitmapA.height;
    Benzer := 0;
    Fark   := Alan;
  end;
end;
- Bir button ile kullanımı. (Sadece tek harf için örnekliyorum, makaleyi uzatmaya lüzum görmüyorum, herşey açık olarak ifade edilmektedir)

Kod: Tümünü seç

procedure TForm1.Button2Click(Sender: TObject);
Var
  iFontS : Integer;
  Alan, Benzer, Fark : Integer;
  Sayac : Integer;
begin
  Image1.Picture.LoadFromFile('D:\Programcilik\Delphi\Pasif06\Captcha_Tespit\MAKALE\Harf_00002.BMP');
  With Image2.Picture.Bitmap.Canvas do begin
    For Sayac := Ord('a') to Ord('z') do begin
      iFontS     := 10;
      Font.Name  := 'Arial';
      Font.Style := [];
      Font.Size  := iFontS;
      While (TextHeight(chr(Sayac))-18) < Image1.Picture.Height do
      begin
        Font.Size  := iFontS;
        Application.ProcessMessages;
        Inc(iFontS);
      end;
      Image2.Picture.Bitmap.Width  := TextWidth ( Chr(Sayac));
      Image2.Picture.Bitmap.Height := TextHeight( Chr(Sayac));
      TextOut(0, 0, chr(Sayac));
      SiyahBeyazYap( Image2 );
      BosluklariKirp(Image2.Picture.Bitmap);
      Image2.Picture.Bitmap.Width  := Image1.Picture.Bitmap.Width;
      Image2.Picture.Bitmap.Height := Image1.Picture.Bitmap.Height;
      Karsilastir( Image1.Picture.Bitmap, Image2.Picture.Bitmap, Alan, Benzer, Fark );
      // iki resim arasındaki fark, toplam alanın %10'undan küçük ise Bulduk (eurika) !!!
      If Fark < Trunc(Alan*10/100)
       then Memo1.Lines.Add( Format('%s (*): %d / %d', [Chr(Sayac), Benzer, Fark]) )
       else Memo1.Lines.Add( Format('%s ( ): %d / %d', [Chr(Sayac), Benzer, Fark]) );
    end;
  end;
end;
Resim


Sonuç tablo : ( g yanındaki (*) dikkatinizi çekerim. )

Kod: Tümünü seç

a ( ): 572 / 279
b ( ): 418 / 433
c ( ): 622 / 229
d ( ): 474 / 377
e ( ): 589 / 262
f ( ): 421 / 430
g (*): 833 / 18
h ( ): 428 / 423
i ( ): 399 / 452
j ( ): 401 / 450
k ( ): 369 / 482
l ( ): 414 / 437
m ( ): 502 / 349
n ( ): 566 / 285
o ( ): 655 / 196
p ( ): 616 / 235
q ( ): 727 / 124
r ( ): 451 / 400
s ( ): 484 / 367
t ( ): 407 / 444
u ( ): 561 / 290
v ( ): 337 / 514
w ( ): 411 / 440
x ( ): 325 / 526
y ( ): 313 / 538
z ( ): 437 / 414
Method 2 : ( ilgilendiğimiz sayfanın kendi ürettiği karakterleri kendileriyle karşılaştırma methodu )

- Bu method ise dlimlere ayırıp incelediğimiz karakter tekleri, eğer tutarlılık arz ediyorsa bunları bir klasörde veya Resource olarak EXE içine gömerek yedekte bulundurur, her birini karşılaştırıp uyumlu olanın karşılığı olan cHarf'dir diyebiliriz.

- Yukardaki verdiğimiz karşılaştırma fonksiyonu tek başına yeterli olmaktadır.

Sonuc :
- Web Sitesinlerinde Resimli Kodları ( CAPTCHA kodlar ) günden güne iyice yaygınlaşıyor ve kusursuzlaşıyor. Biz programcılara ter döktüren CAPTCHA kodlar hakkında çözümleme teknikleri de her geçen gün daha da gelişiyor.

- Bu makalemizde dilim / klavyem döndüğünce bu işin ABC'si olan Canvas operasyonlarını anlatmaya çalıştım.

- Yapay zeka vb. teknikler için de altyapı teşkil ettiğinden ilgilenenlere önemli ve faydalı bir başlangıç olacaktır. Bu örneklediğim karşılaştıma teknikleri, tek başına bir çok sitede yeterli olduğunu defalarca kanıtlamıştır. Şahsen kullanmaktayım. 8)

- Lütfen anlatılanları kavramaya çalışın, biliyorum ki hemen akabinde benden anahtar teslimi kod talepleri illa ki olacaktır. (tecrübe ile sabittir) Zaten balık tutumasını bırakın kodları ardarda koyduğunuzda proje kendiliğinden oluşacak şekilde örnekler sundum. Gördüğünüz üzere Balık kovaya kadar kondu, pazara götürmek için bir zahmet kendiniz biraz çaba gösterin. :lol: Özel isteklere kesinlikle çözüm sunmayacağımı üzülerek bildirmek isterim. :!:

- Çalışmalarınızda başarılar dilerim... :o
En son mrmarman tarafından 11 Mar 2007 05:52 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Resim
Resim ....Resim
Kullanıcı avatarı
karflake
Üye
Mesajlar: 222
Kayıt: 15 Haz 2003 03:57

Mesaj gönderen karflake »

Gerçekten güzel bir makale. Teşekkür ederim.
Kullanıcı avatarı
husonet
Admin
Mesajlar: 2962
Kayıt: 25 Haz 2003 02:14
Konum: İstanbul
İletişim:

Mesaj gönderen husonet »

Hocam Tebrik ederim sizi çok güzel bir makale Teşekkürler.

Gazete manşetleri
* DİKKAT :Lütfen forum kurallarını okuyalım ve uyalım...!
* Warez,crack vs. paylaşımı kesinlikle yasaktır.
Kullanıcı avatarı
Opt2000
Üye
Mesajlar: 216
Kayıt: 09 Tem 2003 10:04

Mesaj gönderen Opt2000 »

Selam,

@mrmarman'ın yazdıklarından farklı olarak benim yazacaklarım daha çok OCR üzerine.

Harflerin karşılaştırılması için ikinci bir yöntem daha var ve eğer titiz çalışılacak olursa daha başarılı sonuçlar verebilir.

1. Harfleri @mrmarman'ın yaptığı gibi önce temizleriz.

2. Daha sonra her harfin siyah beyaz grafiğini çıkarırız. Elimizde her harf için aslında iki boyutlu bir matris var. Bu matrisin sütunlarının toplamı ile elde edilecek olan dizi, aslında bir çok harfi birbirinden ayırır.

3. İkinci maddeyi bu sefer sütunlar için değil, satırlar için yaparız. Böylece I, L gibi birbirine fazla benzeyen harfleri elemiş oluruz.

4. Yazı tipi ailesine göre yukarıdaki sisteme göre kendi kütüphanemizi oluştururuz. Bunu elbette her işlemde değil, sadece bir kere yapmamız yeterli. Yazı tipi ailesi derken, a harfini düşünerek söylüyorum. Daktilo a'sı ile o'nun yanına çizgi çekilen a'nın farkının ortaya çıkması için. Bold tipini eklemeye gerek yok, ama sanırım italik için eklemek gerekebilir.

5. Son olarak artık tahmin edilebileceği gibi, basit oran orantı, tolerans ve eşleşme miktarı dikkate alınarak kütüphanedeki harflerle yapılacak kıyaslama.

Bu sistemin iki tane avantajı var:
1. Yazı tipine daha az bağımlı. Çünkü genelde yazı tipleri tasarlanırken belli bir mantığa göre tasarlanır ve bizim çıkardığımız dizilerin oranlarında çok büyük değişiklikler olmaz.

2. Genel olarak daha hızlı çalışır, çünkü çok büyük bir alanın karşılaştırılmazı yerine, daha küçük karşılaştırmalar yapılır.

@mrmarman yazdığı kod anladığım kadarıyla performans veya doğru sonuç üzerine değil, daha çok sistemin anlaşılması üzerine. Zaten kendisi de eklemiş, çalışan kod istenecektir diye :) Ama sistemi oturtmak isteyen arkadaşlara şu tavsiyelerde bulunmam yerinde olacaktır.

1. Bitmap resimleri önce siyah beyaza çevirin. Ama bunu yaparken özel bir palet kullanın. BMP dosyaları resmi olarak desteklemez, ama 0. rengi siyah, diğer renkleri beyaz olan bir palet yükleyin. Daha sonra standart grayscale fonksiyonu ile siyah/beyaza çevirin ve sizin belirleyeceğiniz bir threshold değeri ile tam beyaz veya tam siyah değerine karar verin (Teknik terimleri bu konularla ilgili arkadaşlar anlayacaktır). 8 bit bir resim ile her zaman daha hızlı işlem yaparsınız, çünkü sayıların ne olması gerektiğini biliyorsunuz :) Üstelik RGB resimlere göre döngünüz üçte bir oranında daha az olur ki, büyük resimler ve toplu işlemlerde programı bir hayli hızlandırır.

2. Kesinlikle Canvas.Pixels kullanmayın. Daha doğrusu standart GDI fonksiyonlarının hiçbirini kullanmayın (Canvas'ın tamamı GDI fonksiyonları üzerine kuruludur), çünkü bu tür işlemler için inanılmaz yavaştırlar. Yavaş olmasının sebebi ise işletim sisteminin araya girmesi ve sizin yapmanız gereken bütün kontrolleri, siz yapsanız bile tekrar yapmasıdır. Aksi takdirde bellek taşmaları olacak ve uygulamalarla beraber işletim sistemi de çökecektir. Bu yüzden Canvas yerine Scanline kullanın. Eğer Scanline'ın dikey olarak nasıl kullanılacağını bilmiyorsanız, öncelikle pointerlar ve resim yapıları ile ilgili ciddi eksiklerinizi kapatın (özellikle BMP dosyalarının yapısı, MS'in tersliği burada da var :) )

3. Programda genel olarak integer kullanacaksınız, ama eğer benim bahsettiğim yöntemi kullanacaksanız, o zaman float tipinde sayılar da kullanacaksınız demektir. Şimdi ilginç bir şey söyleyeceğim, sanılanın aksine double tipleri ile yapılan işlemler öyle çok da yavaş falan değildir, hatta integer matematiği ile başabaştır. Burada asıl sorun double ve integer tiplerin birlikte kullanılmasında çıkar. Meraklı arkadaşlar OpenGL ve/veya DirectX veri yapılarını incemişlerdir, orada RGB'nin tanımı bile float'tır, byte veya integer değil. Çünkü bütün sistemin float üzerine kurulu olmasını isterler. Sebebi de çok basit. 3D dünyasında float'tan kaçmak mümkün değildir. Bu yüzden de bütün veri tiplerini float yapmak, işlemleri integer-float kullanarak yapmaktan çok daha hızlandırır. Bu kısa açıklamadan sonra belki aklınıza farklı bir şey gelebilir, örneğin resmi ilk okuduktan sonra TBitmap yapısından kurtulup, kendi yazacağınız bir float dizisi kullanmak gibi. İnanın program daha hızlı çalışacaktır.

4. Yuvarlama yapmayın, çünkü bir işlemin başında yapılan bir yuvarlama, bir kaç çarpma bölme işleminden sonra inanılmaz bir farka dönüşebilir. Yuvarlamaları hep en sonra bırakın ve hatta mümkünse hiç yapmayın.

5. Programın bütün parametrelerini değişken olarak tanımlayın. Örneğin Threshold değerini 127 olarak sabitlemeyin, onun yerine bir constant tanımlayın ve constant değeri kullanın. Bunu bütün parametreler için üşenmeden uygulayın, çünkü bazı resimlerde ne kadar fark ettiğine inanamayacaksınız (Örneğin taranmış resimler üzerinde çalışırken threshold değeri sizi yoldan da çıkarabilir, kurtarabilir de)

Şimdilik aklıma gelenler bunlar. Bu konuyla ilgilenen arkadaşlara bol bol sabır diliyorum :)

Kolay gelsin,
Bahadır Alkaç
Kullanıcı avatarı
bluekid
Kıdemli Üye
Mesajlar: 541
Kayıt: 11 Haz 2004 10:45
İletişim:

Mesaj gönderen bluekid »

Güzel makale tebrikler.
bir de harflerin deforme edildiği durumlar var.
karşılaştırma kısmına bir az yapay zeka eklemek isterseniz.
Benimde bir vakit önce yazdığım YSA kullanılarak harf tanıma ile ilgili
örnek bir program var
http://derindelimavi.blogspot.com/2006/ ... lamas.html
Kullanıcı avatarı
tuanna
Üye
Mesajlar: 582
Kayıt: 06 Ara 2004 05:01
Konum: Ankara
İletişim:

Mesaj gönderen tuanna »

Gerek Muharrem Beyin Gerekse Opt2000 Makalelerini özenle takip ederim...Bu Makale Çok güzel olmuş...

ayrıca resim hakkındaki teknik bilgilerinden ve ocr ile bilgilerinden dolayı opt2000 de tesekür ederim ...

sölemek istediğim mesele ocr mantığında bu işin yapılabilmesi için bir çok etken gerekiyor

sitenin etüd edilmesi

sitede ki kullanılan fontlar dinamik olabiliyor...(Şuan Değilse Bile Ben Olsam Yapardım..)

artı arkasına fon resmi konduğunu fealn düşününce bu iş çok zorlaşıyor...

Bizim kuracağımız ocr sisteminde ocr sistemi birazda kendisi okuduklarından bir seyler öğrenmeli bence...

Ocr ne kadar başarılı olabileceğini yabancı bileşenleri incelediğimzide ortaya çıkıyor bazen onlarda bile hatalı sonuçlar çıkıyor...

Böle bir durumda nasıl bir yol izlememiz lazım ama anlaşılan % 100 bu işin çözümü şimdilik yok gibi ...
Kullanıcı avatarı
mussimsek
Admin
Mesajlar: 7586
Kayıt: 10 Haz 2003 12:26
Konum: İstanbul
İletişim:

Mesaj gönderen mussimsek »

Konuyla daha önce hiç uğraşmamış biri olarak makale ve diğer eklemeler çok güzel olmuş.

Muharrem hocam teşekkürler : )
Kullanıcı avatarı
Murat DİCLE
Kıdemli Üye
Mesajlar: 702
Kayıt: 19 Nis 2006 04:12
Konum: İstanbul
İletişim:

Mesaj gönderen Murat DİCLE »

Muharrem kardeş,

Ellerine sağlık çok güzel bir makale. Tebrik ederim. Çok şey öğrendim.

Başarılar..
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Mesaj gönderen sabanakman »

Bu tür bir işle kendimce çabalayıp bayağı bir kasmıştım. Biraz birşeyler öğrensem de burada verilenler daha bir içime sindi. Emeği geçen herkesin eline sağlık.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
undefined
Moderator
Mesajlar: 565
Kayıt: 06 Eki 2003 12:01
Konum: Bursa
İletişim:

Mesaj gönderen undefined »

İlginç bir çalışma, eline sağlık hocam.
Kullanıcı avatarı
mucar
Kıdemli Üye
Mesajlar: 247
Kayıt: 17 May 2005 01:14

Mesaj gönderen mucar »

Elinize sağlık, faydalı bir yazı olmuş.
"Evine bakmaktan aciz olan; ilerici, üç kıtaya hükmeden ecdadın mı gerici?"
Kullanıcı avatarı
nitro
Üye
Mesajlar: 1112
Kayıt: 23 Ağu 2004 01:18
Konum: Çanakkale
İletişim:

Mesaj gönderen nitro »

elinize sağlık hocam güzel makale olmuş.
Okulda ödev olarak yapmıştım ben bu projeyi. karşılaştırmalar uzadıkça progrmın sonuç vermesi de gecikiyordu. Ödevden geçmek için verdim projeyi ama Abby FineReader'in algoritmasını merak ettim o dönem.
Koca sayfa minik minik karakterleri algılayıp text'e dönüşrütüyordu.
Hem de benim programın 1 satır yazıyı çözümleyeceği sürede.
Demekki adamlar çok farklı bir algoritma kullanmışlar.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

Yorum yapan herkese teşekkürler. :o

- @nitro OCR mantığı bir çok tekniğin birleşiminden oluşur. Hızı belirleyen kullanılan tekniklerin rantabilitedir.

- Abbyy FineReader'ı da incelediğimde şunu görmüştüm.

1. Başarısını körükleyen en büyük unsur, bünyesinden her dilden bir yazım kılavuzu bulunduruyor olması. :idea:

2. Belli oranlarda image'i digital olarak büyütülerek en az bir kelime bulursa bize daha yüksek çözünürlükte tarayın uyarısı vererek yönlendirmesi.

3. Kelime içerisinde tanıyamadığı bir harf var diyelim. Büyük oranda tanıdıkların harfler yardımıyla, program paketi bünyesindeki yazım kılavuzundan elde ettiği benzer kelime listesinden eksik olan harfe benzeyip benzemediğini araştırarak büyük oranda zaman kazanması. Bu kılavuzlar sayesinde hangi dilde olduğunu dahi keşfedebilir belki ama sizden yine de baştan "hangi dilde bir metin" olduğunun cevabı isteniyor. :idea:
[b]Opt2000[/b] yazdı:2. Kesinlikle Canvas.Pixels kullanmayın. Daha doğrusu standart GDI fonksiyonlarının hiçbirini kullanmayın (Canvas'ın tamamı GDI fonksiyonları üzerine kuruludur), çünkü bu tür işlemler için inanılmaz yavaştırlar.
- Opt2000 yavaşlık konusunda ve Scanline kullanmak konusundaki dediklerine katılıyorum.

- Zaten daha önce başka bir soruda aynı gerekçe ile münazaraya bile girerek SCANLINE kullanımını savunmuş, scanline'ın nasıl kullanıldığı hakkında detaylı ve örnekli bir açıklama yapmıştım. Ref: viewtopic.php?t=6231#34754 Onu inceleyebilirsiniz.

- Bu konuda scanline'e girseydim, o zaman makaleyi bu kadar kısa sürede elle tutulur sonuçla buluşturamazdık. Konu pointer'lara kadar uzardı. Konunun anlaşılmasına balta vurmuş olurdum.
[b]@Opt2000[/b] yazdı:@mrmarman yazdığı kod anladığım kadarıyla performans veya doğru sonuç üzerine değil, daha çok sistemin anlaşılması üzerine. Zaten kendisi de eklemiş, çalışan kod istenecektir diye Ama sistemi oturtmak isteyen arkadaşlara şu tavsiyelerde bulunmam yerinde olacaktır.
- Buradaki söze üzülerek katılamıyorum. Eklediğim "çalışan kod istenecektir" ifadesi, bu verdiğim örneklerin çalışmadığı üzerine değildi. Tersine eksiksiz olarak çalıştığının teyidi ve istendiğinde bu procedure/fonksiyonlar ard arda bir projede eklenerek aynı sonucu alabilecekleri üzerine idi. Zaten resimli örnekte de görebiliyorsunuz.

- Benden şu veya bu sitedeki captcha kodun çözümünü üreten bir proje istenmesine karşı yazılmış bir paragraf idi. Fırsattan istifade ederek bunu da eklemek istedim.

- Herkese çalışmalarında başarılar dilerim...
Resim
Resim ....Resim
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Mesaj gönderen rsimsek »

Eline emeğine sağlık hocam.. Bırak balığı tutup kova ile teslim etmek pişirip vermişsin zaten :)
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

Bu başlığa ulaşıp da özel mesaj veya e-posta ile soru soranların dikkatine... :!:

- Arkadaşlar burada yeterince açık ve net ifadelerle kodları verdim. Çalıştıramadığını söyleyenler oldu. Örnek bir de exe hazırladım. Aşağıda rapid linkini bulabilirsiniz.

- Tamamen burada gördüğünüz kodlardan oluşmuş bir projedir. Yani bu verdiğim kodlar motomot çalışır durumda.

- Örnekte, ADSL Kota sayfasını açarak oradaki CAPTCHA kodun bir Bitmap kopyasını TImage nesnesine alıyor, OCR ederek TEXT'e dönüştürüyor ve sonucu formun başlığında adım adım görüntülüyor.

http://rapidshare.com/files/33969558/ADSLKota.zip.html

- Bu makalemde, bu işin abc'sini göstermeye çalıştım. Kendini geliştirmek ve/veya okulda ödevi bunun üzerine olanlar için, açık kaynak olsun, başlangıç noktası olsun istedim.

- Lütfen mesaj ile kod, program talebinde bulunmayınız. :!:
Resim
Resim ....Resim
Cevapla