Ana içeriğe geç

Python’da Pytesseract ile Optik Karakter Tanıma (OCR) Üzerine Kapsamlı Bir Eğitim

PyTesseract ve OpenCV ile OCR’de optik karakter tanımanın temellerine hakim olun.
· 11 dk. oku

Yapay Zeka ile Keşfedin

Neden Optik Karakter Tanıma (OCR) Öğrenmelisiniz?

Görüntülerden ve belgelerden metni elle çıkarmak oldukça zahmetli ve zaman alıcı olabilir. Neyse ki OCR (Optical Character Recognition), bu süreci otomatikleştirerek görüntüleri düzenlenebilir ve aranabilir metin dosyalarına dönüştürmenizi sağlar.

Öğreneceğiniz teknikler pek çok uygulamada kullanılabilir:

  • Fiziksel belgeleri dijitalleştirme: Tarama belgeleri, PDF’leri veya metin fotoğraflarını düzenlenebilir ve aranabilir dosyalara dönüştürün.
  • Veri girişini otomatikleştirme: Formlar, faturalar, fişler ve diğer belgelerden bilgi çıkarıp veritabanlarını veya e-tabloları otomatik doldurun.
  • Erişilebilirliği artırma: Kitaplar, menüler veya tabelalar için görme engelli kişiler adına dijital metin sürümleri oluşturun. Ardından metni seslendirmek için metin okuma araçlarını kullanabilirsiniz.
  • Sürücüsüz araçlar: Güvenli gezinme için trafik işaretlerini ve plaka numaralarını tanıyın.

Bu eğitim, Tesseract OCR motoruna ve onun Python API’si olan PyTesseract’a odaklanacak. Koda başlamadan önce, OCR’a adanmış bazı popüler kütüphanelere kısaca göz atalım.

Python’daki En İyi Açık Kaynak OCR Kütüphaneleri

OCR yaygın ve güncel bir problem olduğundan, bunu çözmeye çalışan birçok açık kaynak kütüphane vardır. Bu bölümde, yüksek performans ve doğrulukları sayesinde en çok popülerlik kazananları ele alacağız.

Tesseract

Tesseract OCR, geliştiriciler arasında en popüler olan açık kaynak bir optik karakter tanıma motorudur. Bu listedeki diğer araçlar gibi Tesseract da metin içeren görüntüleri alıp düzenlenebilir metne dönüştürebilir.

Avantajlar

  • Geniş topluluğa sahip, yaygın kullanılan ve olgun bir kütüphane
  • 100’den fazla dili destekler
  • Ücretsiz ve açık kaynak

Dezavantajlar

  • Bazı derin öğrenme tabanlı çözümlere kıyasla doğruluk daha düşük olabilir
  • Sınırlı yapılandırma seçenekleri

Easy OCR

EasyOCR, zahmetsiz Optik Karakter Tanıma (OCR) için tasarlanmış bir Python kütüphanesidir. Görüntülerden metin çıkarma konusunda kullanıcı dostu bir yaklaşım sunarak adına uygun hareket eder.

Avantajlar

  • Kullanıcı dostu ve kurulumu kolay
  • Derin öğrenme modelleriyle yüksek doğruluk
  • Kutudan çıktığı haliyle çeşitli dilleri destekler

Dezavantajlar

  • Önceden eğitilmiş modellere bağımlıdır; bu modeller büyük boyutlu olabilir
  • Basit görevlerde Tesseract’tan daha yavaş olabilir

Keras OCR

Keras-OCR, popüler bir derin öğrenme çerçevesi olan Keras üzerine inşa edilmiş bir Python kütüphanesidir. Hazır OCR modelleri ve yeni OCR modelleri oluşturmak için uçtan uca bir eğitim hattı sunar.

Avantajlar

  • Derin öğrenme tabanlı yaklaşım; çeşitli metin türlerinde yüksek doğruluk sunar
  • Özelleştirilebilir model seçimi ve eğitimi
  • Karmaşık yerleşimler veya el yazısında daha doğru olabilir

Dezavantajlar

  • En iyi performans için GPU gerektirir
  • Derin öğrenme doğası nedeniyle daha dik bir öğrenme eğrisi
  • Özel modelleri eğitmek zaman alabilir

İşte aralarındaki farkları, avantajları ve dezavantajları özetleyen bir tablo:

Paket Adı

Avantaj

Dezavantajlar

Tesseract (pytesseract)

Olgun, yaygın kullanılan, kapsamlı destek

Daha yavaş, karmaşık yerleşimlerde daha düşük doğruluk

EasyOCR

Kullanımı basit, birden fazla model

Daha düşük doğruluk, sınırlı özelleştirme

Keras-OCR

Daha yüksek doğruluk, özelleştirilebilir

GPU gerektirir, daha dik öğrenme eğrisi

Bu eğitimde, Tesseract’ın Python API’si olan PyTesseract’a odaklanacağız. Basit görsellerden metin çıkarmayı, metin etrafına sınırlayıcı kutular çizmeyi ve taranmış bir belgeyle vaka çalışması yapmayı öğreneceğiz.

PyTesseract & OpenCV ile OCR: Adım Adım Rehber

Kurulum

PyTesseract, ayrı bir CLI yazılımı olan resmi Tesseract motorunun üzerinde çalışır. Pytesseract’ı kurmadan önce motorun kurulu olması gerekir. Aşağıda farklı platformlar için kurulum talimatları yer alıyor.

Ubuntu veya WSL2 için (benim tercihim):

$ sudo apt update && sudo apt upgrade
$ sudo apt install tesseract-ocr
$ sudo apt install libtesseract-dev

Homebrew kullanan Mac için:

$ brew install tesseract

Windows için, bu GitHub sayfasındaki talimatları izleyin.

Sonrasında yeni bir sanal ortam oluşturun. Ben Conda kullanacağım:

$ conda create -n ocr python==3.9 -y
$ conda activate ocr

Daha sonra OCR için pytesseract’ı ve görüntü işleme için opencv’yi kurmanız gerekir:

$ pip install pytesseract
$ pip install opencv-python

Bu eğitimi Jupyter’da takip ediyorsanız, yeni sanal ortamınızın bir çekirdek olarak eklenmesi için bu komutları aynı terminal oturumunda çalıştırın:

$ pip install ipykernel
$ ipython kernel install --user --name=ocr

Artık kod yazmaya başlayabiliriz.

Temel kullanım

Gerekli kütüphaneleri içe aktararak başlıyoruz:

import cv2
import pytesseract

Görevimiz aşağıdaki görüntüden metni okumak:

PyTesseract ve OpenCV ile OCR yapılacak örnek görüntü

Önce görüntü yolunu tanımlayıp cv2.imread fonksiyonuna veriyoruz:

# Read image
easy_text_path = "images/easy_text.png"
easy_img = cv2.imread(easy_text_path)

Ardından, yüklü görüntüyü metni çıkarmak için pytesseract’ın image_to_string fonksiyonuna iletiyoruz:

# Convert to text
text = pytesseract.image_to_string(easy_img)
print(text)
This text is
easy to extract.

Bu kadar kolay! Şimdi yaptığımızı bir fonksiyona dönüştürelim:

def image_to_text(input_path):
   """
   A function to read text from images.
   """
   img = cv2.imread(input_path)
   text = pytesseract.image_to_string(img)

   return text.strip()

Fonksiyonu biraz daha zor bir görüntüde kullanalım:

PyTesseract ve OpenCV ile OCR yapılacak bir başka örnek görüntü

Görüntüde daha fazla noktalama işareti ve farklı yazı tiplerinde metin olduğu için daha zorlu.

# Define image path
medium_text_path = "images/medium_text.png"

# Extract text
extracted_text = image_to_text(medium_text_path)
print(extracted_text)
Home > Tutorials » Data Engineering

Snowflake Tutorial For Beginners:
From Architecture to Running
Databases

Learn the fundamentals of cloud data warehouse management using
Snowflake. Snowflake is a cloud-based platform that offers significant
benefits for companies wanting to extract as much insight from their data as
quickly and efficiently as possible.

Jan 2024 - 12 min read

Fonksiyonumuz neredeyse kusursuz çalıştı. Bir noktayı ve “>” işaretini karıştırdı ancak sonuç genel olarak kabul edilebilir.

Metin etrafına sınırlayıcı kutular çizme

OCR’de yaygın bir işlem, metin etrafına sınırlayıcı kutular çizmektir. Bu işlem PyTesseract’ta desteklenir.

Önce, yüklü bir görüntüyü image_to_data fonksiyonuna iletiyoruz:

from pytesseract import Output

# Extract recognized data from easy text
data = pytesseract.image_to_data(easy_img, output_type=Output.DICT)

Output.DICT bölümü, görüntü ayrıntılarının bir sözlük olarak döndürülmesini sağlar. İçine bakalım:

data
{'level': [1, 2, 3, 4, 5, 5, 5, 4, 5, 5, 5],
'page_num': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
'block_num': [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
'par_num': [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
'line_num': [0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2],
'word_num': [0, 0, 0, 0, 1, 2, 3, 0, 1, 2, 3],
'left': [0, 41, 41, 236, 236, 734, 1242, 41, 41, 534, 841],
'top': [0, 68, 68, 68, 68, 80, 68, 284, 309, 284, 284],
'width': [1658, 1550, 1550, 1179, 380, 383, 173, 1550, 381, 184, 750],
'height': [469, 371, 371, 128, 128, 116, 128, 155, 130, 117, 117],
'conf': [-1, -1, -1, -1, 96, 95, 95, -1, 96, 96, 96],
'text': ['', '', '', '', 'This', 'text', 'is', '', 'easy', 'to', 'extract.']}

Sözlük, görüntü hakkında çok sayıda bilgi içerir. Öncelikle conf ve text anahtarlarına dikkat edin. İkisi de 11 uzunluğunda:

len(data["text"])
11

Bu, pytesseract’ın 11 kutu çizdiği anlamına gelir. conf, güveni (confidence) ifade eder. -1’e eşitse, ilgili kutu tek tek kelimeler yerine metin bloklarının etrafına çizilmiştir.

Örneğin, ilk dört width ve height değerine bakarsanız, geri kalanlara göre daha büyüktür; çünkü bu kutular önce ortadaki tüm metnin, sonra her bir metin satırının ve tüm görüntünün etrafına çizilmiştir.

Ayrıca:

  • left, sınırlayıcı kutunun sol üst köşesinden görüntünün sol kenarına olan mesafedir.
  • top, sınırlayıcı kutunun sol üst köşesinden görüntünün üst kenarına olan mesafedir.
  • width ve height, sınırlayıcı kutunun genişliği ve yüksekliğidir.

Bu bilgileri kullanarak, OpenCV’de görüntünün üzerine kutuları çizelim.

Önce verileri ve uzunluğunu tekrar çıkarıyoruz:

from pytesseract import Output

# Extract recognized data
data = pytesseract.image_to_data(easy_img, output_type=Output.DICT)
n_boxes = len(data["text"])

Ardından, bulunan kutu sayısı kadar bir döngü oluşturuyoruz:

for i in range(n_boxes):
   if data["conf"][i] == -1:
       continue

Döngünün içinde, conf -1’e eşitse mevcut yinelemeyi atlayan bir koşul oluşturuyoruz. Daha büyük sınırlayıcı kutuları atlamak görüntümüzü temiz tutacaktır.

Daha sonra mevcut kutunun koordinatlarını, özellikle sol üst ve sağ alt köşelerin konumlarını tanımlıyoruz:

for i in range(n_boxes):
   if data["conf"][i] == -1:
       continue
   # Coordinates
   x, y = data["left"][i], data["top"][i]
   w, h = data["width"][i], data["height"][i]

   # Corners
   top_left = (x, y)
   bottom_right = (x + w, y + h)

Kutu rengi ve piksel cinsinden kalınlık gibi bazı parametreleri belirledikten sonra tüm bilgileri cv2.rectangle fonksiyonuna iletiyoruz:

for i in range(n_boxes):
   if data["conf"][i] == -1:
       continue
   # Coordinates
   x, y = data["left"][i], data["top"][i]
   w, h = data["width"][i], data["height"][i]

   # Corners
   top_left = (x, y)
   bottom_right = (x + w, y + h)

   # Box params
   green = (0, 255, 0)
   thickness = 3  # pixels

   cv2.rectangle(
       img=easy_img, pt1=top_left, pt2=bottom_right, color=green, thickness=thickness
   )

Fonksiyon, kutuları orijinal görüntülerin üzerine çizecek. Görüntüyü kaydedip bakalım:

# Save the image
output_image_path = "images/text_with_boxes.jpg"
cv2.imwrite(output_image_path, easy_img)
True

Her kelimenin etrafına çizilmiş sınırlayıcı kutularla örnek bir görüntü. PyTesseract ve OpenCV kullanılarak gerçekleştirildi.

Sonuç tam istediğimiz gibi!

Şimdi, yaptıklarımızın hepsini yine bir fonksiyona koyalım:

def draw_bounding_boxes(input_img_path, output_path):
   img = cv2.imread(input_img_path)

   # Extract data
   data = pytesseract.image_to_data(img, output_type=Output.DICT)
   n_boxes = len(data["text"])

   for i in range(n_boxes):
       if data["conf"][i] == -1:
           continue
       # Coordinates
       x, y = data["left"][i], data["top"][i]
       w, h = data["width"][i], data["height"][i]

       # Corners
       top_left = (x, y)
       bottom_right = (x + w, y + h)

       # Box params
       green = (0, 255, 0)
       thickness = 1  # The function-version uses thinner lines

       cv2.rectangle(img, top_left, bottom_right, green, thickness)

   # Save the image with boxes
   cv2.imwrite(output_path, img)

Ve fonksiyonu orta zorluktaki metinde kullanalım:

output_path = "images/medium_text_with_boxes.png"

draw_bounding_boxes(medium_text_path, output_path)

Her kelimenin etrafına çizilmiş sınırlayıcı kutularla başka bir örnek görüntü. PyTesseract ve OpenCV kullanılarak gerçekleştirildi.

Daha zor görüntü için bile sonuç mükemmel!

Vaka Çalışması: Python ile Bir PDF Dosyasında OCR

Örnek bir taranmış PDF dosyası üzerinde bir vaka çalışması yapalım. Pratikte, görüntüler yerine böyle taranmış PDF’lerle çalışmanız oldukça olasıdır:

PyTesseract kullanılarak OCR uygulanacak örnek bir taranmış belge.

PDF’yi GitHub’daki bu sayfadan indirebilirsiniz.

Sonraki adım, Poppler adlı bir PDF işleme yazılımı gerektiren pdf2image kütüphanesini kurmaktır. İşte platforma özgü talimatlar:

Mac için:

$ brew install poppler
$ pip install pdf2image

Linux ve WSL2 için:

$ sudo apt-get install -y poppler-utils
$ pip install pdf2image

Windows için, PDF2Image dokümanlarındaki talimatları izleyebilirsiniz.

Kurulumdan sonra ilgili modülleri içe aktarıyoruz:

import pathlib
from pathlib import Path

from pdf2image import convert_from_path

convert_from_path fonksiyonu, verilen bir PDF’yi bir dizi görüntüye dönüştürür. İşte bir PDF dosyasının her sayfasını belirtilen bir dizine görüntü olarak kaydeden bir fonksiyon:

def pdf_to_image(pdf_path, output_folder: str = "."):
   """
   A function to convert PDF files to images
   """
   # Create the output folder if it doesn't exist
   if not Path(output_folder).exists():
       Path(output_folder).mkdir()

   pages = convert_from_path(pdf_path, output_folder=output_folder, fmt="png")

   return pages

Bunu belgemizde çalıştıralım:

pdf_path = "scanned_document.pdf"

pdf_to_image(pdf_path, output_folder="documents")
[<PIL.PngImagePlugin.PngImageFile image mode=RGB size=1662x2341>]

Çıktı, tek bir görüntü PngImageFile nesnesi içeren bir listedir. documents dizinine bakalım:

$ ls documents
2d8f6922-99c4-4ef4-a475-ef81effe65a3-1.png

Görüntü orada; o halde başta oluşturduğumuz image_to_text fonksiyonuna verip çıkarılan metnin ilk birkaç yüz karakterini yazdıralım:

scanned_img_path = "documents/2d8f6922-99c4-4ef4-a475-ef81effe65a3-1.png"

print(image_to_text(scanned_img_path)[:377])
PEU Business report

New customer's development
and increasing the sale of product

My country economy at this season keeps escaping from Odoba of business though holds a crude oil
high so on unstable element that continues still, and recovering gradually and well.
In the IT industry, there is an influence such as competing intensification in narrowing investment field.

Metni dosyayla karşılaştırırsak, her şey yolunda çalışıyor—biçimlendirme ve aralıklar korunmuş, metin doğru. Peki çıkarılan metni nasıl paylaşırız?

Pekâlâ, çıkarılan PDF metnini paylaşmak için en iyi format yine bir PDF dosyasıdır! PyTesseract, metin içeren herhangi bir görüntüyü ham, metin içinde arama yapılabilir bir PDF dosyasına dönüştüren image_to_pdf_or_hocr fonksiyonuna sahiptir. Bunu taranmış görüntümüzde kullanalım:

raw_pdf = pytesseract.image_to_pdf_or_hocr(scanned_img_path)

with open("searchable_pdf.pdf", "w+b") as f:
   f.write(bytearray(raw_pdf))

searchable_pdf’nin görünümü şöyle:

Taranmış bir PDF belgesi üzerinde gerçekleştirilen OCR’nin sonucunu gösteren bir GIF.

Gördüğünüz gibi dosyadan metni vurgulayıp kopyalayabiliyorum. Ayrıca, orijinal PDF’nin tüm öğeleri korunmuş.

OpenCV’de OCR için Görüntü Ön İşleme Teknikleri

OCR için tek bir herkese uyan yaklaşım yoktur. Bugün ele aldığımız teknikler, diğer görüntü türlerinde çalışmayabilir. Belirli görüntüler için en uygun ayarları bulmak adına farklı görüntü ön işleme tekniklerini ve Tesseract yapılandırmalarını denemenizi öneririm.

OCR’de en önemli faktör görüntü kalitesidir. Doğru taranmış, tamamen dik ve yüksek kontrastlı (siyah beyaz) görüntüler, herhangi bir OCR yazılımıyla en iyi sonucu verme eğilimindedir. Unutmayın, siz metni okuyabiliyor olsanız bile bilgisayarınız aynı derecede okuyamayabilir.

Görüntüleriniz Tesseract’ın yüksek kalite standartlarını karşılamıyorsa ve çıktı anlamsızsa, uygulayabileceğiniz bazı ön işleme adımları vardır.

1. Gri tonlamaya dönüştürme

Öncelikle, renkli görüntüleri gri tona dönüştürerek başlayın. Bu, tanıma sürecini şaşırtabilecek renk farklılıklarını ortadan kaldırarak doğruluğu artırabilir. OpenCV’de bu işlem şu şekilde görünür:

def grayscale(image):
   """Converts an image to grayscale.

   Args:
       image: The input image in BGR format.

   Returns:
       The grayscale image.
   """
   return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

2. Gürültü azaltma

Özellikle taranmış belgeler, her zaman tertemiz ve tekdüze arka planlarla gelmez. Ayrıca bazı görüntüler, yaş nedeniyle yıpranmış eski belgelerden olabilir. İşte bir örnek:

OCR uygulanacak gürültülü örnek bir görüntü.

Görüntüdeki gürültü kaynaklı yapıtları azaltmak için (ör. medyan bulanıklaştırma) gibi gürültü giderme filtreleri uygulayın; aksi halde OCR sırasında yanlış yorumlamalara yol açabilirler. OpenCV’de medianBlur fonksiyonunu kullanabilirsiniz:

def denoise(image):
   """Reduces noise in the image using a median blur filter.

   Args:
       image: The input grayscale image.

   Returns:
       The denoised image.
   """
   return cv2.medianBlur(image, 5)  # Adjust kernel size as needed

3. Keskinleştirme

Bazı durumlarda görüntüyü keskinleştirmek, kenarları belirginleştirerek özellikle bulanık veya düşük çözünürlüklü görüntülerde karakter tanımayı iyileştirebilir. OpenCV’de Laplace filtresi uygulayarak keskinleştirme yapılabilir:

def sharpen(image):
   """Sharpens the image using a Laplacian filter.

   Args:
       image: The input grayscale image.

   Returns:
       The sharpened image (be cautious with sharpening).
   """
   kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
   return cv2.filter2D(image, -1, kernel)

4. Binarizasyon

Bazı görüntüler için binarizasyon (görüntüyü siyah beyaza dönüştürme) faydalı olabilir. Ön plan (metin) ile arka plan arasındaki en uygun ayrımı bulmak için farklı eşikleme tekniklerini deneyin.

Ancak, binarizasyon aydınlatma farklılıklarına duyarlı olabilir ve her zaman gerekli olmayabilir. İşte binarize edilmiş bir görüntünün nasıl göründüğüne dair bir örnek:

Örnek görüntü: solda orijinal, sağda OpenCV’de binarize edilmiş sürüm.

Binarizasyonu OpenCV’de gerçekleştirmek için adaptiveThreshold fonksiyonunu kullanabilirsiniz:

def binarize(image):
   """Binarizes the image using adaptive thresholding.

   Args:
       image: The input grayscale image.

   Returns:
       The binary image.
   """
   thresh = cv2.adaptiveThreshold(
       image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2
   )

   return thresh

5. Diğer teknikler

Pek çok başka ön işleme tekniği vardır, örneğin:

  • Genişletme (Dilation): küçük ve ince yazı tiplerini kalınlaştırarak tanımayı iyileştirme
  • Aşındırma (Erosion): kalın metni aşındırarak doğruluğu artırma. Kalın yazı tipli tarihî belgelerde yaygındır.
  • Canny kenar tespiti
  • Eğiklik düzeltme: metin satırlarının eğikliğini (skew) düzeltme. Hatalı taranan belgelerde yaygındır

Görüntü kalitesini artırma hakkında daha fazla bilgiyi Tesseract dokümantasyonunun bu sayfasından edinebilirsiniz.

Sonuç

Bu yazıda, OCR gibi dinamik bir problemi öğrenmeye ilk adımları attınız. Önce basit görüntülerden metin çıkarmayı ele aldık, ardından karmaşık biçimlendirmeye sahip daha zor görüntülere geçtik.

Ayrıca, taranmış PDF’lerden metin çıkarmak için uçtan uca bir iş akışı ve çıkarılan metni tekrar aranabilir hale gelecek şekilde PDF olarak kaydetmeyi öğrendik. Makaleyi, Tesseract’a vermeden önce OpenCV ile görüntü kalitesini artırmaya yönelik bazı ipuçlarıyla tamamladık.

Görüntüyle ilgili problemleri çözme konusunda daha fazla bilgi edinmek isterseniz, göz atabileceğiniz bazı bilgisayarla görme kaynakları şunlar:

Bexruz (Bex) Tuychiev

Yazar

Bexruz (Bex) Tuychiev

2 yılı aşkın deneyime sahip bir veri bilimi içerik üreticisiyim ve Medium’da en büyük takipçi kitlelerinden birine sahibim. Yapay zekâ ve makine öğrenimi üzerine, biraz da alaycı bir üslupla yazılmış, ayrıntılı makaleler kaleme almayı seviyorum; çünkü onları biraz daha az sıkıcı hale getirmek için bir şeyler yapmak gerekiyor. 130’un üzerinde makale ve bir de DataCamp kursu ürettim; bir diğeri de hazırlık aşamasında. İçeriklerim 5 milyondan fazla kişi tarafından görüldü; bunların 20 bini Medium ve LinkedIn’de takipçim oldu. 

Python OCR SSS

Neden bu kadar uzunum?

Genetik.

Konular

İlgili