Beranda Blog Store
Computer Vision

OCR Bahasa Indonesia dengan Tesseract dan Python: Instalasi, Pra-pemrosesan Gambar, dan Meningkatkan Akurasi

23 Agu 2026 Hartono 5 menit baca 8 Dilihat

Halo, Rekan ArtonLabs. Artikel ini lahir dari pengalaman menghadapi arsip kertas yang harus bisa dicari, dan semoga berguna untuk arsip Anda juga.

Mengubah pindaian dokumen atau foto menjadi teks yang bisa dicari adalah kebutuhan yang muncul di hampir setiap kantor: arsip surat, formulir, nota, ijazah. Tesseract adalah mesin OCR open source yang matang, punya paket bahasa Indonesia, dan bisa dipanggil dari Python. Tetapi akurasinya sangat bergantung pada apa yang Anda berikan kepadanya. Tulisan ini memasang Tesseract, memakainya dari Python, dan terutama membahas pra-pemrosesan gambar yang mengubah hasil dari "lumayan" menjadi "bisa dipakai".

Daftar Isi

Instalasi Tesseract dan Paket Bahasa

sudo apt install -y tesseract-ocr tesseract-ocr-ind tesseract-ocr-eng
tesseract --version
tesseract --list-langs

Paket tesseract-ocr-ind berisi data bahasa Indonesia; eng berguna karena dokumen Indonesia sering mengandung istilah Inggris, dan Tesseract bisa memakai beberapa bahasa sekaligus dengan -l ind+eng. Coba dari terminal dulu:

tesseract surat.png keluaran -l ind
cat keluaran.txt

Memanggil dari Python

pip install pytesseract pillow opencv-python-headless
import pytesseract
from PIL import Image
teks = pytesseract.image_to_string(Image.open("surat.png"), lang="ind")
print(teks)

data = pytesseract.image_to_data(Image.open("surat.png"), lang="ind",
                                 output_type=pytesseract.Output.DICT)
# data['text'], data['conf'], data['left'], data['top'] per kata

image_to_data mengembalikan tiap kata beserta keyakinan dan posisinya. Keyakinan itu berguna untuk menandai bagian yang perlu diperiksa manusia, dan posisi berguna untuk mengambil nilai dari kolom tertentu di formulir.

Pra-pemrosesan yang Menentukan

Tesseract paling baik pada teks hitam di atas putih, tegak, dengan tinggi huruf sekitar 30 piksel. Foto ponsel jarang seperti itu. Urutan pra-pemrosesan yang kami pakai:

import cv2, numpy as np

def siapkan(path):
    img = cv2.imread(path)
    abu = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 1. Perbesar kalau teksnya kecil
    abu = cv2.resize(abu, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
    # 2. Hilangkan derau ringan
    abu = cv2.bilateralFilter(abu, 9, 75, 75)
    # 3. Binarisasi adaptif: tahan terhadap bayangan dan pencahayaan tak rata
    biner = cv2.adaptiveThreshold(abu, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                  cv2.THRESH_BINARY, 31, 15)
    return biner

cv2.imwrite("siap.png", siapkan("foto.jpg"))
print(pytesseract.image_to_string(Image.open("siap.png"), lang="ind"))

Binarisasi adaptif adalah langkah yang paling sering memberi lompatan akurasi pada foto, karena bayangan di satu sisi halaman tidak lagi membuat separuh teks hilang. Untuk halaman yang miring, hitung sudutnya dari kontur teks (atau pakai pytesseract.image_to_osd untuk orientasi) dan putar dengan cv2.warpAffine. Untuk dokumen pindaian yang bersih, resize dan threshold sederhana biasanya sudah cukup; jangan memakai semua langkah kalau tidak perlu, karena filter yang berlebihan justru mengikis huruf tipis.

Mode Segmentasi Halaman

Tesseract perlu tahu bentuk tata letaknya. Parameter --psm mengaturnya: 3 (bawaan) untuk halaman penuh dengan analisis tata letak otomatis, 4 untuk kolom teks, 6 untuk satu blok teks seragam, 7 untuk satu baris, dan 11 untuk teks tersebar tanpa urutan. Untuk formulir atau nota, --psm 6 sering jauh lebih baik daripada bawaan:

pytesseract.image_to_string(img, lang="ind", config="--psm 6")

Kalau Anda hanya butuh angka, batasi karakternya: config="--psm 7 -c tessedit_char_whitelist=0123456789.,". Membatasi ruang tebakan adalah cara termurah menaikkan akurasi pada bidang yang formatnya diketahui.

Mengambil Bidang Tertentu dari Formulir

Untuk formulir dengan tata letak tetap (KTP, nota, surat dengan kop yang sama), OCR seluruh halaman lalu mencari-cari nilainya kurang andal. Lebih baik potong daerah bidangnya dengan koordinat yang diketahui, lalu OCR potongan itu dengan mode yang sesuai:

img = siapkan("formulir.jpg")
nomor = img[210:260, 380:720]          # y1:y2, x1:x2, ditentukan sekali dari contoh
teks = pytesseract.image_to_string(nomor, lang="ind",
        config="--psm 7 -c tessedit_char_whitelist=0123456789")

Koordinat ditentukan sekali dari satu contoh yang sudah diluruskan dan diskalakan ke ukuran tetap. Untuk formulir yang difoto, luruskan dulu dengan mendeteksi empat sudut kertas dan cv2.getPerspectiveTransform; setelah itu koordinat bidang bisa dipercaya. Pendekatan ini jauh lebih akurat daripada mencari nilai di teks hasil OCR satu halaman penuh.

Kamus Kata dan Istilah Khusus

Tesseract memakai kamus bahasa untuk memperbaiki tebakan. Untuk dokumen penuh nama tempat, istilah hukum, atau kode produk, berikan daftar kata tambahan lewat berkas teks satu kata per baris dan opsi --user-words daftar.txt. Kata yang ada di daftar lebih mungkin dikenali dengan benar. Kombinasi -l ind+eng juga membantu untuk dokumen yang mencampur keduanya, dengan bahasa utama disebut lebih dulu.

Dokumen PDF dan Banyak Halaman

sudo apt install -y poppler-utils
pip install pdf2image
from pdf2image import convert_from_path
for i, halaman in enumerate(convert_from_path("arsip.pdf", dpi=300), 1):
    halaman.save(f"hal-{i}.png")
    print(f"== halaman {i}")
    print(pytesseract.image_to_string(halaman, lang="ind"))

Kalau PDF-nya sudah berisi lapisan teks (dibuat dari pengolah kata, bukan pindaian), jangan OCR sama sekali; ambil teksnya langsung dengan pdftotext atau pustaka pypdf, hasilnya sempurna dan seketika. Periksa dulu dengan pdffonts arsip.pdf: kalau daftar fontnya kosong, itu pindaian dan perlu OCR.

Render pada 300 dpi; 150 dpi terlalu kecil untuk huruf dokumen biasa. Untuk arsip besar, jalankan sebagai pekerjaan latar (misalnya dengan Django-Q2), simpan teks per halaman ke database, dan buat indeks pencarian; itulah yang membuat arsip pindaian akhirnya bisa dicari.

Mengukur Akurasi

Ambil 20 sampai 30 dokumen, ketik teks sebenarnya (atau perbaiki hasil OCR dengan teliti), lalu hitung jarak sunting antara hasil OCR dan teks asli; pustaka jiwer memberi CER (character error rate) dan WER (word error rate) dalam dua baris. Ukur sebelum dan sesudah tiap perubahan pra-pemrosesan. Tanpa angka ini, Anda akan menghabiskan sore memutar parameter berdasarkan perasaan.

Batasan dan Kapan Memakai Model Lain

Tesseract lemah pada tulisan tangan, foto dengan perspektif ekstrem, dan tata letak rumit seperti tabel bersarang. Untuk kasus itu, model OCR berbasis deep learning seperti PaddleOCR atau EasyOCR, atau model multimodal, memberi hasil lebih baik dengan biaya komputasi lebih besar. Untuk dokumen cetak yang dipindai dengan layak, Tesseract dengan pra-pemrosesan yang benar tetap pilihan yang ringan, cepat, dan sepenuhnya berjalan di server sendiri.

Penutup

OCR yang berguna adalah 20 persen mesin OCR dan 80 persen persiapan gambar serta pemilihan mode yang tepat. Pasang paket bahasa Indonesia, binarisasi adaptif, pilih --psm yang sesuai, dan ukur dengan CER pada contoh nyata; dengan itu, arsip kertas bertahun-tahun bisa mulai dicari dalam hitungan hari.

Terima kasih sudah membaca, Rekan ArtonLabs. Kalau Anda menemukan trik pra-pemrosesan lain yang ampuh, bagikan lewat halaman kontak.