EasyOCR adalah library OCR siap pakai dari JaidedAI untuk Python: pip install easyocr, dua baris kode, lalu teks yang tertanam di dalam gambar langsung keluar sebagai string. Lisensinya Apache-2.0, mendukung 80+ bahasa, dan bekerja sebagai pipeline dua model PyTorch — sebuah detektor CRAFT yang memberi kotak pada area yang dianggap teks, lalu recognizer yang membaca karakter di dalam tiap kotak. Bobot model pralatihnya akan terunduh otomatis saat pertama kali dipanggil. Secara fungsi, ini adalah alternatif self-hosted untuk Tesseract dan PaddleOCR, bukan API OCR cloud per halaman.
API dasarnya singkat: Reader(['en']), lalu readtext(). Namun beban deploy-nya jauh lebih besar—sekitar 2 GB PyTorch di environment ini dan kira-kira 1 GB memory resident puncak dalam proses baru yang diukur. Saya merender 36 fixture PNG bahasa Inggris, menjalankan easyocr 1.7.2 di CPU, dan menilai hasil bacaan karakter demi karakter terhadap ground truth yang dibuat. Ukuran dan orientasi memicu penurunan CER paling tajam; dashboard juga memperlihatkan kegagalan pada deteksi token pendek dan salah baca tanda dolar.
Kegagalan paling mencolok ada pada parameter yang paling sering direkomendasikan semua orang. rotation_info punya reputasi di issue tracker sebagai solusi untuk gambar yang terputar, jadi parameter ini saya uji pada tiga salinan teks yang diputar secara ortogonal. Pada 270°, ia benar-benar bekerja seperti klaimnya, menurunkan character error rate dari 0.83 menjadi 0.10. Pada 180°, hasilnya setengah berhasil: dari 0.85 ke 0.67, dengan satu frasa hilang. Pada 90°, justru memburuk, dari 0.81 ke 0.92, dan recognizer mulai mengembalikan teks cermin. Parameter sama, daftar sudut sama, tapi hasilnya tiga macam — jadi menyalakannya tidak otomatis berarti “rotasi sudah ditangani.” 36 fixture yang sama juga menghasilkan jurang tajam pada ukuran font, salah baca tanda dolar yang konsisten, dan satu prediksi saya yang ternyata benar-benar meleset.
Dua model dalam satu jas hujan
EasyOCR bukan satu model tunggal. Ini pipeline dua tahap, dan mengetahui tahap mana yang gagal akan mengubah cara Anda melakukan debugging.
Tahap pertama adalah CRAFT, si detector. Tugasnya hanya lokalisasi — menentukan di mana dalam gambar ada teks, lalu mengembalikan kotak. Ia tidak membaca karakter. Tahap kedua adalah CRNN recognizer — ekstraksi fitur ResNet, lalu BiLSTM, lalu decoding greedy CTC — yang membaca karakter di dalam tiap kotak. Keduanya berjalan di PyTorch. Di CPU, recognizer dijalankan dengan quantization dinamis ke int8 secara default, itulah sebabnya ia lebih cepat dan lebih ringan daripada yang terlihat dari jumlah parameter mentahnya.

Konsekuensi praktisnya: EasyOCR punya dua mode gagal yang sangat berbeda, dan masing-masing butuh solusi berbeda. Kalau detektor tidak pernah menggambar kotak, tidak ada tuning recognizer yang akan membantu — karakter tidak pernah masuk pipeline. Kalau kotaknya ada tapi string-nya salah, itu problem recognizer dan preprocessing mungkin bisa menyelamatkan. Hampir semua thread “EasyOCR melewatkan teks saya” yang pernah saya baca mencampuradukkan keduanya.
Status proyek saat ini, dicek pada 27 Juli 2026: 29.825 bintang, 528 issue terbuka, Apache-2.0, dan v1.7.2 dari September 2024, dengan push terakhir ke master pada Desember 2025. Tanggal-tanggal itu tidak membuktikan stabilitas arsitektur atau kesehatan maintenance. Sebelum mengadopsi, pastikan kompatibilitas dengan stack Python/PyTorch Anda, respons maintainer terbaru, dan issue yang relevan dengan input Anda.
OCR sering dikaitkan dengan solving CAPTCHA, dan itu bukan use case di sini. Tidak ada yang diuji terhadap, dan tidak ada yang mendukung, upaya mengalahkan tantangan bot-detection. Ruang lingkup tugasnya adalah membaca teks dari gambar dan screenshot yang memang Anda berhak membacanya.
Apa yang saya ukur, dan apa yang tidak tercakup oleh angka-angka ini
Test set-nya adalah 36 PNG buatan saya sendiri: 35 gambar satu baris yang menyapu tujuh font, delapan ukuran, tujuh level kontras, tujuh sudut skew, tiga rotasi ortogonal, dan tiga latar belakang — ditambah satu screenshot dashboard sintetis dengan 19 elemen berlabel individual. Setiap gambar dibuat dari string tetap (Sphinx of black quartz, judge my vow. 1234567890 — 48 karakter, campuran huruf besar-kecil, digit, tanda baca) dalam langkah yang sama saat label ground-truth ditulis, jadi gambar dan labelnya secara fisik tidak mungkin melenceng satu sama lain.
Akurasi diukur dengan character error rate (CER): jarak Levenshtein dalam karakter dibagi panjang ground truth. CER 0 berarti bacaan sempurna. CER 0.10 berarti kira-kira satu dari sepuluh karakter salah. Saya melaporkan CER peka huruf besar-kecil sebagai headline dan CER tidak peka huruf besar-kecil di sampingnya, karena ternyata sebagian besar “error” ada di sana.
Batasan ini lebih penting daripada angkanya:
- Hanya bahasa Inggris. Recognizer
english_g2. EasyOCR mengiklankan 80+ bahasa; saya hanya menguji satu. Tidak ada yang di sini berbicara tentang skrip non-Latin, yang justru menjadi fokus banyak perbandingan OCR akademik yang dipublikasikan. - Hanya sintetik. Teks dirender, bukan difoto. Tidak ada noise kamera, artefak JPEG, pencahayaan, atau perspektif.
- Tanpa handwriting. Proyeknya sendiri menyebut handwriting belum didukung.
- Hanya CPU. macOS arm64,
gpu=False. MPS tersedia di mesin ini, tetapi EasyOCR memakai CPU pada sistem yang bukan CUDA. Performa GPU tidak diukur, jadi tidak ada angka GPU di sini. - Satu mesin, satu versi. easyocr 1.7.2, torch 2.13.0, Python 3.12.
Jadi: ini adalah kurva terkontrol satu variabel yang menunjukkan tepat di mana fidelitas mulai pecah, pada teks Latin yang dirender dengan bersih. Ini bukan skor korpus dunia nyata, dan tidak dimaksudkan menggantikannya.
Bukti bisa diperiksa, bukan terjebak di notebook. Generator fixture dan string persisnya ada di tests/build_fixtures.py dan tests/fixtures/ground_truth.json; pengenalan, timing, dan capture resource ada di tests/run_easyocr.py; dan tests/metrics.py menghitung error rate yang dilaporkan dari output mentah. Catatan pengenalan dan metrik agregat yang dihasilkan disimpan di artifacts/raw/. Menjalankan ulang rantai itu berguna untuk mengecek mesin dan versi ini. Tetapi itu tetap tidak menjawab bagaimana EasyOCR akan berperilaku pada foto ponsel, bahasa, layout, atau pipeline preprocessing Anda, jadi penerimaan produksi sebaiknya menambahkan input yang representatif, bukan memperlakukan fixture ini sebagai suite sertifikasi.
Satu jebakan harness perlu saya tandai, karena hampir membuat headline angka yang salah. Pass metrik pertama saya melaporkan CER 0.375 pada Arial hitam yang bersih, yang jelas buruk untuk input semudah itu. Masalahnya bukan EasyOCR. Detektor memisahkan satu baris visual menjadi kotak kata dan kotak angka, lalu sort naive berdasarkan y lalu x membuat angka terbaca lebih dulu. Setelah diperbaiki dengan grouping yang sadar baris (kotak dikelompokkan berdasarkan overlap vertikal, lalu dibaca dari kiri ke kanan), font bersih turun ke sekitar 0.04–0.10. Kalau Anda membangun evaluasi OCR sendiri, jebakan ini juga menunggu Anda.
Setup: instalasinya kecil, dependensinya tidak

pip install easyocr
Itu seluruhnya, dan ini jujur soal sangat sedikit hal. Paketnya sendiri ringan; yang ikut terbawa adalah PyTorch, sekitar 2 GB. Lalu saat pertama kali Anda memanggil readtext(), EasyOCR diam-diam mengunduh bobot model ke ~/.EasyOCR/model/ — total 93,7 MiB, terdiri dari 79,30 MiB untuk detector CRAFT (craft_mlt_25k.pth) dan 14,44 MiB untuk recognizer bahasa Inggris (english_g2.pth).
Tidak banyak tutorial yang menegaskan ini, jadi: run pertama Anda butuh akses jaringan dan akan berhenti sejenak untuk unduhan, dan setiap deployment dalam container harus mengemas bobot ini ke dalam image atau menanggung unduhan saat cold start. Setelah cache terbentuk, semuanya offline.
Inisialisasi dingin Reader() — model dari disk masuk ke RAM, plus proses quantization int8 — memakan 1,3–1,7 detik antar run. Setelah itu:
import easyocr
reader = easyocr.Reader(['en'], gpu=False)
result = reader.readtext('screenshot.png')
Lalu jalan. Dua baris, tidak perlu konfigurasi, tidak perlu berburu checkpoint. Kata “easy” dalam namanya memang layak di tahap ini — friksinya sepenuhnya ada di berat dependensi, bukan API-nya.
Batas teks bersih: hampir sempurna di karakter, tapi kapitalisasi tak selalu tepat
Tujuh font sistem, hitam di atas putih, 32 px, string yang sama setiap kali:
| Font | CER (peka huruf besar-kecil) | CER (tidak peka huruf besar-kecil) |
|---|---|---|
| Georgia | 0.0625 | 0.0000 |
| Times | 0.0417 | 0.0417 |
| Comic Sans | 0.0417 | 0.0208 |
| Arial | 0.0833 | 0.0208 |
| Verdana | 0.0833 | 0.0208 |
| Impact | 0.0833 | 0.0208 |
| Courier | 0.1042 | 0.0417 |
| Rata-rata | 0.0714 | 0.0238 |
Rata-rata CER 0.071, turun menjadi 0.024 setelah kapitalisasi dinormalisasi. Itulah temuan utamanya. EasyOCR bukan kehilangan karakter pada teks Latin yang bersih — ia justru menangkap bentuk dengan benar, tetapi kapitalisasinya yang meleset.
Secara spesifik, kata kecil vow dirender menjadi VOW pada enam dari tujuh font (Comic Sans memilih kompromi Vow). Impact menambah of → Of sebagai bonus. Kesalahan berulang lain adalah tanda baca: titik di akhir kalimat kembali sebagai : atau _ pada beberapa font. Georgia menghasilkan bacaan sempurna begitu Anda berhenti peduli pada kapitalisasi.
Ini bentuk temuan yang sangat berguna. Kalau langkah lanjutan Anda adalah fuzzy matching, pencarian kata kunci, atau memberi teks ke language model, salah kapital hampir tidak berbiaya. Tetapi jika langkah berikutnya adalah membandingkan string secara eksak dengan key database, biayanya bisa total. Normalisasi case sebelum dibandingkan, dan separuh error rate yang tampak dari EasyOCR langsung lenyap.
Courier menjadi yang terburuk (0.1042) juga masuk akal: font monospace memberi spasi karakter yang tidak natural lebar, yang lebih sulit untuk decoder CTC yang belajar dari jarak huruf yang umum.
Jatuhnya terjadi tepat di ukuran yang disebut dokumen

readtext() punya parameter terdokumentasi, min_size=10, yang membuang kotak terdeteksi yang lebih pendek dari 10 piksel. Kebanyakan orang melewatkannya. Ini adalah angka paling berpengaruh di API untuk siapa pun yang mengekstrak screenshot atau PDF, dan berikut yang terjadi saat tinggi glyph diratakan:
| Tinggi render px | CER | Apa yang terjadi |
|---|---|---|
| 8 | 0.7708 | Jatuh total — kotak berada di bawah filter min_size dan dibuang; hanya fragmen yang tersisa |
| 10 | 0.1458 | Menurun — tepat di batas minimum, detektor memecah baris menjadi 3 kotak |
| 12 | 0.0417 | Pulih |
| 16 | 0.0000 | Bacaan sempurna |
| 20 | 0.0208 | Bersih |
| 28 | 0.0208 | Bersih |
| 40 | 0.0625 | Bersih (flip case muncul lagi) |
| 64 | 0.0625 | Bersih (flip case) |
Lonjakan dari 0.04 ke 0.77 antara 12 px dan 8 px bukan degradasi bertahap. Itu filter yang memang bekerja seperti dokumentasinya, dan hasilnya teks di bawah kira-kira 10 px praktis tak terlihat oleh EasyOCR default.
Titik manisnya ada di 12–28 px, dengan CER penuh 0 pada 16 px. Di atas 40 px, CER naik lagi — bukan karena karakter makin sulit dibaca, melainkan karena flip vow → VOW kembali muncul. Teks besar tidak lebih sulit dibaca; hanya saja ia tidak lagi mendapat manfaat dari spasi yang membuat 16 px menjadi sangat pas.
Bagi siapa pun yang mengekstrak teks dari screenshot: cek tinggi glyph hasil render sebelum menyalahkan model. Dashboard yang ditangkap pada 1× di layar HiDPI, atau halaman PDF yang diraster pada 72 DPI, sering kali membuat teks body berada di bawah 10 px. Tangkap pada 2× atau upscale sebelum OCR, dan Anda akan menghindari seluruh kelas laporan bug “EasyOCR mengabaikan setengah halaman saya”. Jika tidak bisa, turunkan min_size — tetapi harapkan noise, karena filter ini memang ada untuk menekan deteksi sampah.
Rotasi: toleransi 10°, dan perbaikan yang tidak simetris
Mulai dari skew. Sudut kecil, Arial 32 px, setelan default versus rotation_info=[90,180,270]:
| Sudut skew | CER (default) | CER (dengan rotation_info) |
|---|---|---|
| 0° | 0.0833 | 0.0833 |
| 5° | 0.0417 | 0.0417 |
| 10° | 0.0208 | 0.0833 |
| 15° | 0.2917 | 0.3750 |
| 20° | 0.7500 | 0.7708 |
| 30° | 0.8958 | 0.8750 |
| 45° | 0.8958 | 0.8750 |
EasyOCR default menangani skew hingga sekitar 10° tanpa masalah besar (CER ≤ 0.083), mulai goyah di 15°, dan hilang pada 20°. rotation_info tidak membantu skew, yang masuk akal begitu Anda tahu fungsinya — ia hanya mencoba ulang pada sudut yang Anda daftarkan, sedangkan skew 15° bukan 90, 180, atau 270. Pada 10° justru sedikit lebih buruk (0.021 → 0.083), karena retry pada sudut yang salah bisa menang dalam voting confidence.
Rotasi ortogonal-lah yang menjadi aneh:
| Rotasi | CER (default) | CER (dengan rotation_info) | Pulih? |
|---|---|---|---|
| 90° | 0.8125 | 0.9167 | Tidak — malah lebih buruk |
| 180° | 0.8542 | 0.6667 | Sebagian |
| 270° | 0.8333 | 0.1042 | Ya |
Parameter sama. Daftar sudut sama. Tiga hasil berbeda.
Pada 270°, rotation_info melakukan persis yang dijanjikan thread issue: CER turun dari 0.83 menjadi 0.10, bacaan yang benar-benar usable. Pada 180°, hasilnya setengah berhasil — CER membaik ke 0.67, tetapi frasa my vow. hilang seluruhnya. Pada 90°, hasilnya mundur, dari 0.81 menjadi 0.92, dan output mentah menjelaskan alasannya: recognizer mengembalikan string cermin. VOW kembali sebagai MOA. quartz kembali sebagai zuuenb. Baca lewat cermin, semuanya benar — trik pesta yang lucu, tapi pipa data yang tidak berguna.
Saya mengecek ini terhadap prediksi mentah, bukan metrik agregat, karena dugaan pertama saya adalah “urutan penggabungan yang mengacaukan hasil.” Ternyata bukan artefak join — memang itulah yang benar-benar dikembalikan EasyOCR.
Mekanismenya masih hipotesis, bukan hasil pengukuran; tidak ada eksperimen konvensi rotasi yang dijalankan. Pillow merender sudut positif berlawanan arah jarum jam, jadi hanya gambar hasil render 270° yang kebetulan selaras dengan orientasi retry yang ditangani recognizer dengan baik, sedangkan kasus 90° memiliki retry dengan skor terbaik yang jatuh pada orientasi terbalik. Apa pun mekanismenya, pelajaran operasionalnya tidak bergantung pada itu:
Fixture ini menunjukkan bahwa rotation_info tidak bisa diasumsikan berperilaku simetris di semua orientasi. Validasi rotasi yang diperkirakan ada di input Anda; normalisasi orientasi di upstream adalah kandidat mitigasi, bukan keharusan yang dibuktikan oleh tiga contoh render.
Prediksi yang saya salah
Awalnya saya mengira kontras rendah akan menjadi titik lemah EasyOCR. Teks abu-abu pucat di atas putih adalah cerita klasik kegagalan OCR, dan ada jalur penyelamatan yang terdokumentasi untuk itu: contrast_ths=0.1 dengan adjust_contrast=0.5, yang menjalankan ulang kotak berkontras rendah dengan salinan yang diperkuat dan mengambil hasil yang paling yakin.
Fitur itu tidak pernah aktif, karena tidak pernah dibutuhkan.
| Abu-abu foreground | Kontras Weber | CER (default) | CER (adjust_contrast=1.0) |
|---|---|---|---|
| 0 (hitam) | 1.000 | 0.0833 | 0.0833 |
| 64 | 0.749 | 0.0833 | 0.0833 |
| 110 | 0.569 | 0.0833 | 0.0833 |
| 150 | 0.412 | 0.1042 | 0.1042 |
| 180 | 0.294 | 0.0625 | 0.0625 |
| 200 | 0.216 | 0.0417 | 0.0417 |
| 220 | 0.137 | 0.0417 | 0.0417 |
CER tidak pernah keluar dari band bersih, bahkan sampai Weber 0.14 — abu-abu 220 di atas putih, yang cukup pucat sampai saya harus menyipit untuk memastikan teksnya memang ada. Dan kolom peningkatan kontras identik dengan kolom default di setiap langkah, karena default-nya sudah berhasil.
Latar belakang memberi cerita yang sama. Teks hitam di seluruhnya:
| Latar belakang | CER |
|---|---|
| Panel biru muda solid | 0.083 |
| Gradien vertikal | 0.021 |
| Noise Gaussian (μ200, σ22) | 0.000 |
Bacaan sempurna pada fixture paling berisik di set ini.
Ruang lingkupnya sempit: ini adalah kontras rendah warna solid tanpa noise, bukan struk foto dengan noise sensor dan kompresi JPEG. Dalam set fixture ini, geometri dan token pendek adalah sumber kegagalan terbesar; variasi warna dan noise sintetis yang diuji tidak demikian.
Skenario nyata: menarik angka dari screenshot dashboard
Inilah kasus yang paling sering terjadi dalam pekerjaan OCR Python. Seseorang mengirim screenshot dashboard internal, atau Anda menjalankan pipeline scraping Python ke halaman analytics yang penuh grafik, tempat angka hanya ada sebagai pixel terender, dan Anda ingin nilainya menjadi data.
Saya merender jendela “Sales Dashboard” — header gelap dengan judul dan badge avatar bulat, tiga panel KPI, tiga tombol, tabel 2×3 — lalu memberi label semua 19 elemen teks dengan string dan kotak pixel yang tepat, kemudian mencocokkan output EasyOCR terhadapnya berdasarkan overlap kotak.
Recall deteksi: 16 dari 19. Tiga yang terlewat:
- badge satu huruf, "A"
- sel tabel "Q1"
- sel tabel "Q2"
Dan "Q3" terdeteksi. Font sama, ukuran sama, kolom sama — detektor mempertahankan satu token dua karakter dan membuang dua yang lain. Deteksinya tidak konsisten di antara sel yang secara visual mirip. Karena output bersifat deterministik dalam run ini, ini bukan bukti perilaku acak seperti “lempar koin.” Masalah kualitas screenshot yang terkait dilaporkan di #460.
Pada 16 elemen yang ditemukan, teksnya hampir sempurna: CER rata-rata 0.027, dengan 13 dari 16 tepat. Judul, label, tombol ("Save", "Cancel", "Export CSV"), header kolom, dan angka dengan pemisah koma semuanya kembali dengan CER 0. 1,284 dibaca benar, termasuk komanya.
Tiga bacaan yang tidak sempurna semuanya kesalahan yang sama. Nilai mata uang:
| Ground truth | Bacaan EasyOCR |
|---|---|
$57,912 | S57,912 |
$18,330 | S18,330 |
$25,178 | S25,178 |
$12,004 | $12,004 (benar) |
Tiga dari empat tanda dolar berubah menjadi huruf kapital S. Secara visual, ini cukup masuk akal — tetapi artinya setiap field mata uang dalam ekstraksi Anda tinggal satu karakter dari sampah, dan float() sederhana akan error pada semuanya.
Jika pipeline screenshot Anda berisi label pendek atau mata uang, validasi mitigasi kandidat seperti upscaling, crop dengan padding, ekspektasi field yang dibatasi, atau post-processing yang peka simbol. Tidak satu pun yang dibenchmark di sini, dan regex yang mengubah S di awal bisa merusak nilai yang sah. Terapkan koreksi hanya jika skema dan aturan validasi membuatnya aman.
Biaya menjalankannya
Angka pada mesin yang sama (macOS arm64, CPU, satu host, diukur saat mungkin ada beban paralel — anggap ini sebagai bentuk, bukan benchmark universal):
| Metrik | Nilai |
|---|---|
| Bobot model di disk | 93,7 MiB (79,30 detector + 14,44 recognizer) |
| Peak resident memory, proses CPU baru | 984,5 MiB |
Inisialisasi dingin Reader() | 1,3–1,7 dtk |
| Latensi hangat, satu baris bersih 48 karakter (p50) | ~0,062 dtk (p25–p75: 0,059–0,067 dtk, n=20) |
detail=0 vs detail=1 | ~sama (median 0,062 vs 0,063 dtk) |
Biaya utamanya bukan 94 MB bobot — melainkan sekitar 1 GB memory resident per worker process, di atas instalasi torch ~2 GB. Itu angka yang menentukan apakah ini muat di container Anda, dan itu angka yang jarang disebut siapa pun.
Kecepatannya cukup baik untuk kasus mudah. Di bawah 0,1 detik warm untuk satu baris bersih di CPU sangat bisa dipakai. Tapi itu memang kasus mudah: satu baris pendek berkontras tinggi. Keluhan berulang "EasyOCR memakan puluhan detik di CPU" berkaitan dengan dokumen besar multi-region pada ukuran canvas penuh, dan saya tidak mereproduksinya — workload-nya berbeda, dan saya menyebutnya sebagai referensi, bukan klaim.
Satu mitos kecil untuk dibunuh: detail=0 tidak membuat EasyOCR lebih cepat. Itu hanya menghapus bounding box dan confidence score dari nilai return. Komputasinya sudah terjadi. Median-nya hanya beda satu milidetik, yang merupakan noise.
Kelebihan dan kekurangan
Kelebihan
- Recall karakter pada teks Latin yang dirender bersih pada dasarnya sempurna — CER rata-rata 0.071 peka huruf besar-kecil, 0.024 setelah case dinormalisasi, dengan CER penuh 0 yang bisa dicapai pada 16 px.
- API benar-benar dua baris.
Reader(['en'])lalureadtext(), tanpa konfigurasi, tanpa memilih model. - Jauh lebih tahan kontras daripada yang sering diceritakan: tidak jatuh sampai Weber 0.14 pada teks bersih, dan latar belakang noise/gradien/berwarna tidak membuatnya turun (fixture noise gaussian menghasilkan bacaan sempurna).
- Hampir sempurna pada elemen screenshot yang berhasil dideteksi: CER rata-rata 0.027, 13 dari 16 tepat, termasuk angka dengan pemisah koma.
- Deterministik. Setiap angka akurasi di sini identik byte-ke-byte di dua run proses yang sepenuhnya independen; hanya timing yang berubah.
- Apache-2.0 dan self-hosted, tanpa biaya penggunaan vendor; biaya komputasi, memory, storage, dan queue tetap menjadi biaya operasional Anda.
Kekurangan
- Jatuh keras di bawah batas
min_size=10yang terdokumentasi — CER 0.77 pada 8 px. Teks UI kecil tak terlihat secara default. - Toleransi skew berhenti di sekitar 10° dan ambruk pada 20°.
rotation_infobukan perbaikan yang simetris: 270° pulih, 180° sebagian, 90° makin buruk dan mengembalikan teks cermin.- Detektor menjatuhkan token pendek yang berdiri sendiri — satu badge satu huruf dan dua sel dua karakter, sementara satu sel lain dengan format sama tetap tertangkap.
- Salah baca sistematis
$→Spada nilai mata uang (3 dari 4). - Memory resident ~1 GB per proses, ditambah dependensi torch ~2 GB.
- Rilis terbaru berasal dari September 2024; proyeknya stabil, bukan sedang berkembang cepat.
Siapa yang cocok memakainya, dan siapa yang sebaiknya mundur
Evaluasi EasyOCR jika input Anda bersih, tegak, teks ter-render dengan ukuran yang layak—screenshot, capture UI, PDF yang diraster, atau laporan yang digenerate—dan Anda menginginkan pipeline Python self-hosted tanpa biaya penggunaan vendor. Hasil sintetik bahasa Inggris pada CPU berlaku untuk jalur itu; foto, handwriting, dan skrip lain perlu diuji terpisah.
Jangan lanjut jika input Anda menggambarkan salah satu hal ini. Foto — angka saya adalah teks render sintetik dan tidak mengatakan apa pun tentang noise kamera, perspektif, atau pencahayaan. Handwriting — proyeknya sendiri tidak mengklaim dukungan itu. Skrip non-Latin — EasyOCR mendukung 80+ bahasa, tetapi saya hanya menguji satu, dan perbandingan akademik yang dipublikasikan menjadi rujukan di sana, bukan sweep sintetik bahasa Inggris. Input yang diputar sembarang — kecuali Anda melakukan koreksi orientasi sendiri terlebih dulu. Deploy dengan memori ketat — satu gigabyte per worker cepat sekali menumpuk.
Sebelum memilih OCR, periksa DOM dan respons network. Jika nilai yang Anda butuhkan sudah ada sebagai teks terstruktur, mengekstraknya langsung akan menghindari error deteksi dan pengenalan OCR. OCR cocok saat pixel adalah satu-satunya representasi yang tersedia.
Alternatif, dan di mana stack kami cocok
EasyOCR berlisensi Apache-2.0 dan self-hosted, tanpa biaya penggunaan vendor tetapi dengan biaya komputasi dan operasional yang nyata. PaddleOCR, Tesseract, dan vision-language model tidak dijalankan melalui benchmark ini, jadi tidak ada kesimpulan head-to-head yang dibuat.
Perbandingan yang lebih menarik bukan OCR vs OCR. Melainkan apakah Anda memang perlu OCR sama sekali.
Sebagian besar pekerjaan ekstraksi screenshot yang saya lihat sebenarnya adalah workaround untuk web page yang sulit di-scrape — tabel yang dirender JavaScript, dashboard di balik login, situs yang melawan. Mengambil screenshot lalu OCR memang terasa jalan paling mudah, tetapi Anda membuang teks terstruktur yang sebenarnya sudah ada, lalu membayar “pajak tanda dolar” untuk mendapatkan versi yang lebih buruk dari data itu.
Catatan penulis: Thunderbit adalah opsi terkelola kami untuk ekstraksi dari web page. Ia tidak dijalankan melalui fixture gambar ini. Batas yang relevan adalah representasi sumber: gunakan ekstraksi DOM/network ketika data web terstruktur tersedia, dan evaluasi OCR ketika pixel adalah satu-satunya sumber.
Bacaan terkait dari test bench yang sama: perbandingan lengkap scraper open-source, ulasan Crawl4AI, dan pandangan yang lebih luas tentang ekstraksi berbasis AI untuk halaman yang menolak selector.
Coba Thunderbit untuk Ekstraksi Data Web
Putusan
Perlu memakai EasyOCR? Ya, jika gambar Anda tegak, glyph Anda setidaknya setinggi 12 piksel, dan Anda membaca skrip Latin. Di dalam batas itu, ia sangat baik — CER rata-rata 0.071 pada teks bersih, 0.024 setelah case dinormalisasi, bacaan sempurna pada 16 px, dan ketahanan terhadap kontras lebih baik daripada reputasinya. API-nya benar-benar dua baris dan outputnya deterministik, yang lebih penting daripada yang sering orang akui saat debugging pipeline.
Di luar batas itu, ia gagal dengan cara yang spesifik dan bisa dipelajari. Teks di bawah 10 px hilang ke filter min_size. Skew di atas 20° merusak bacaan. rotation_info memperbaiki satu orientasi ortogonal, setengah memperbaiki yang lain, dan membuat yang ketiga lebih buruk dengan teks cermin. Token satu huruf dan dua karakter jatuh dari detektor sementara tetangganya tetap lolos. Tanda dolar berubah jadi huruf S.
Kegagalan fixture datang dari kedua tahap: kotak yang terlewat atau salah orientasi di sisi geometri, dan kebingungan tanda dolar di sisi recognizer. Perlakukan upscaling, normalisasi orientasi, crop ber-padding, dan perbaikan simbol berbasis skema sebagai kandidat yang perlu divalidasi, bukan fix yang aman secara universal.
Jangan mengujinya seperti yang hampir saya lakukan, dengan harness evaluasi yang rusak dan angka yang tidak Anda pahami. Render fixture Anda sendiri, ketahui ground truth secara presisi, dan temukan jurang Anda sendiri.
Coba Thunderbit untuk Ekstraksi Data Web Get Started Free
FAQ
Apakah EasyOCR cukup akurat untuk ekstraksi teks screenshot di production?
Pada dashboard sintetis, elemen yang berhasil dicocokkan memiliki mean CER 0.027 dengan 13 dari 16 tepat. Tiga dari 19 elemen tidak terdeteksi, dan tiga dari empat tanda dolar berubah menjadi S. Apakah itu bisa diterima — dan apakah upscaling atau perbaikan berbasis skema membantu — harus diuji pada layout target.
Berapa ukuran font minimum yang bisa dibaca EasyOCR?
Secara praktis, sekitar 12 piksel tinggi glyph yang dirender. Parameter readtext() min_size=10 membuang kotak terdeteksi yang lebih pendek dari 10 px, dan efeknya adalah jurang, bukan lereng: CER 0.77 pada 8 px, 0.15 pada 10 px, 0.04 pada 12 px, dan 0 pada 16 px. Band bersih dalam sweep saya ada di 12–28 px. Jika sumber Anda adalah screenshot HiDPI yang ditangkap pada 1× atau PDF yang diraster pada 72 DPI, upscale dulu sebelum OCR, bukan menurunkan min_size, karena filter itu memang ada untuk menekan deteksi sampah.
Apakah rotation_info memperbaiki gambar yang terputar di EasyOCR?
Tidak andal, dan tidak simetris. Dengan rotation_info=[90,180,270] pada tiga salinan yang diputar ortogonal dari kalimat yang sama, gambar 270° pulih bersih (CER 0.83 → 0.10), gambar 180° hanya sebagian (0.85 → 0.67, dengan satu frasa hilang), dan gambar 90° justru lebih buruk (0.81 → 0.92) sambil mengembalikan teks cermin seperti VOW → MOA. Parameter ini juga tidak membantu skew kecil, karena ia hanya mencoba ulang pada sudut yang Anda daftarkan. Koreksi orientasi sebelum memanggil EasyOCR, jangan bergantung pada parameter ini.
Berapa besar memory dan disk yang dibutuhkan EasyOCR?
Bobot modelnya 93,7 MiB, diunduh ke ~/.EasyOCR/model/ saat pertama dipakai—79,30 MiB untuk detector plus 14,44 MiB untuk recognizer bahasa Inggris. Peak resident memory pada proses CPU baru yang diukur adalah 984,5 MiB, di atas instalasi torch sekitar 2 GB. Inisialisasi dingin reader memakan 1,3–1,7 detik; satu baris bersih kemudian berjalan sekitar p50 0,062 detik di mesin ini. detail=0 mengubah bentuk return, bukan runtime yang diukur.
Apakah EasyOCR gratis untuk penggunaan komersial, dan apakah masih dirawat? Ya, lisensinya Apache-2.0, yang permisif dan ramah komersial. Per 27 Juli 2026 repositori berada di 29.825 bintang dengan 528 issue terbuka, rilis terbaru adalah v1.7.2 dari September 2024, dan push terakhir ke master terjadi pada Desember 2025. Artikan itu sebagai stabil, bukan ditinggalkan — arsitekturnya tidak banyak berubah belakangan ini dan aktivitasnya berpindah ke issue tracker. Pastikan sendiri lisensi dan status rilisan saat ini sebelum membangun di atasnya.


