PythonでOCR(文字認識)を実装する方法【Tesseract・EasyOCR完全ガイド】

フリーランスボード

20万件以上の案件から、副業に最適なリモート・週3〜の案件を一括検索できるプラットフォーム。プロフィール登録でAIスカウトが自動的にマッチング案件を提案。市場統計や単価相場、エージェントの口コミも無料で閲覧可能なため、本業を続けながら効率的に高単価の副業案件を探せます。フリーランスボード

ITプロパートナーズ

週2〜3日から働ける柔軟な案件が業界トップクラスの豊富さを誇るフリーランスエージェント。エンド直契約のため高単価で、週3日稼働でも十分な報酬を得られます。リモートや時間フレキシブルな案件も多数。スタートアップ・ベンチャー中心で、トレンド技術を使った魅力的な案件が揃っています。専属エージェントが案件紹介から契約交渉までサポート。利用企業2,000社以上の実績。ITプロパートナーズ

Midworks 10,000件以上の案件を保有し、週3日〜・フルリモートなど柔軟な働き方に対応。高単価案件が豊富で、報酬保障制度(60%)や保険料負担(50%)など正社員並みの手厚い福利厚生が特徴。通勤交通費(月3万円)、スキルアップ費用(月1万円)の支給に加え、リロクラブ・freeeが無料利用可能。非公開案件80%以上、支払いサイト20日で安心して稼働できます。Midworks

OCR(Optical Character Recognition:光学文字認識)は、画像やPDFから文字を抽出する技術で、現代のデジタル化に欠かせません。本記事では、Pythonを使ったOCR実装の方法を、初心者から上級者まで理解できるよう徹底解説します。

OCRとは

OCRは、紙の文書や画像に含まれる文字を、コンピュータが処理可能なテキストデータに変換する技術です。主な用途:

  • 文書のデジタル化
  • 名刺・レシートの自動読み取り
  • 車のナンバープレート認識
  • 手書き文字の認識
  • PDF内テキストの抽出

主要なPython OCRライブラリ

1. Tesseract(pytesseract)

  • 最も人気の高いオープンソースOCRエンジン
  • 100以上の言語をサポート
  • 高い精度と豊富な設定オプション

2. EasyOCR

  • 深層学習ベースのOCR
  • セットアップが簡単
  • 80以上の言語をサポート

3. PaddleOCR

  • 中国のBaiduが開発
  • 高精度で高速
  • 多言語対応

環境構築とインストール

Tesseractのインストール

# Windows
# https://github.com/UB-Mannheim/tesseract/wiki からダウンロード

# macOS
brew install tesseract tesseract-lang

# Ubuntu/Debian
sudo apt install tesseract-ocr tesseract-ocr-jpn

# Pythonライブラリ
pip install pytesseract pillow opencv-python

EasyOCRのインストール

pip install easyocr

Tesseractを使った基本的なOCR

最小コード実装

import pytesseract
from PIL import Image

# 画像からテキスト抽出
text = pytesseract.image_to_string(Image.open('image.jpg'), lang='jpn')
print(text)

OpenCVとの組み合わせ

import cv2
import pytesseract

img = cv2.imread('image.jpg')
text = pytesseract.image_to_string(img, lang='jpn+eng')
print(text)

設定オプション付きOCR

import pytesseract
from PIL import Image

config = '--psm 8 --oem 3 -c tessedit_char_whitelist=0123456789'
text = pytesseract.image_to_string(Image.open('numbers.jpg'), config=config)
print(text)

EasyOCRを使った実装

基本的な使用方法

import easyocr

reader = easyocr.Reader(['ja', 'en'])
result = reader.readtext('image.jpg')
for text in result:
    print(text[1])  # 認識されたテキストを出力

信頼度付きで結果取得

import easyocr

reader = easyocr.Reader(['ja', 'en'])
results = reader.readtext('image.jpg', detail=1)
for (bbox, text, confidence) in results:
    if confidence > 0.7:  # 信頼度70%以上のみ表示
        print(f'{text}: {confidence:.2f}')

画像前処理によるOCR精度向上

グレースケール変換とノイズ除去

import cv2
import pytesseract

def preprocess_image(img_path):
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    denoised = cv2.medianBlur(gray, 5)
    return denoised

img = preprocess_image('noisy_image.jpg')
text = pytesseract.image_to_string(img, lang='jpn')
print(text)

二値化処理

import cv2
import pytesseract

def binarize_image(img_path):
    img = cv2.imread(img_path, 0)
    _, binary = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    return binary

img = binarize_image('low_contrast.jpg')
text = pytesseract.image_to_string(img, lang='jpn')
print(text)

エッジ検出と輪郭抽出

import cv2
import pytesseract

def extract_text_regions(img_path):
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 50, 150)
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    texts = []
    for contour in contours:
        x, y, w, h = cv2.boundingRect(contour)
        if w > 50 and h > 20:  # 最小サイズフィルタ
            roi = img[y:y+h, x:x+w]
            text = pytesseract.image_to_string(roi, lang='jpn')
            texts.append(text.strip())
    return texts

実用的な応用例

名刺読み取りシステム

import cv2
import pytesseract
import re

def extract_business_card_info(img_path):
    img = cv2.imread(img_path)
    text = pytesseract.image_to_string(img, lang='jpn+eng')
    
    # 電話番号抽出
    phone = re.findall(r'\d{2,4}-\d{2,4}-\d{4}', text)
    # メールアドレス抽出
    email = re.findall(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', text)
    
    return {'phone': phone, 'email': email, 'text': text}

PDFからのテキスト抽出

import pdf2image
import pytesseract

def pdf_to_text(pdf_path):
    pages = pdf2image.convert_from_path(pdf_path)
    text = ""
    for page in pages:
        text += pytesseract.image_to_string(page, lang='jpn+eng')
    return text

# 使用例
text = pdf_to_text('document.pdf')
print(text)

WebカメラでリアルタイムOCR

import cv2
import pytesseract

def realtime_ocr():
    cap = cv2.VideoCapture(0)
    while True:
        ret, frame = cap.read()
        text = pytesseract.image_to_string(frame, lang='jpn+eng')
        if text.strip():
            print(text.strip())
        
        cv2.imshow('Camera', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    cap.release()
    cv2.destroyAllWindows()

OCR精度向上のテクニック

画像サイズの最適化

import cv2
from PIL import Image

def optimize_for_ocr(img_path, scale_factor=2):
    img = cv2.imread(img_path)
    height, width = img.shape[:2]
    resized = cv2.resize(img, (width * scale_factor, height * scale_factor))
    return resized

文字領域の自動検出

import cv2
import pytesseract

def detect_text_boxes(img_path):
    img = cv2.imread(img_path)
    data = pytesseract.image_to_data(img, output_type=pytesseract.Output.DICT)
    
    results = []
    for i in range(len(data['text'])):
        if int(data['conf'][i]) > 60:  # 信頼度60%以上
            x, y, w, h = data['left'][i], data['top'][i], data['width'][i], data['height'][i]
            text = data['text'][i]
            results.append({'text': text, 'bbox': (x, y, w, h)})
    
    return results

エラーハンドリングとパフォーマンス最適化

例外処理付きOCR

import pytesseract
from PIL import Image
import logging

def safe_ocr(img_path, lang='jpn+eng'):
    try:
        img = Image.open(img_path)
        text = pytesseract.image_to_string(img, lang=lang)
        return text.strip()
    except Exception as e:
        logging.error(f"OCR処理エラー: {e}")
        return ""

バッチ処理

import os
import pytesseract
from PIL import Image
from concurrent.futures import ThreadPoolExecutor

def batch_ocr(image_folder, output_file):
    def process_image(img_path):
        try:
            text = pytesseract.image_to_string(Image.open(img_path), lang='jpn+eng')
            return f"{img_path}: {text.strip()}\n"
        except:
            return f"{img_path}: 処理エラー\n"
    
    image_files = [os.path.join(image_folder, f) for f in os.listdir(image_folder)]
    
    with ThreadPoolExecutor(max_workers=4) as executor:
        results = list(executor.map(process_image, image_files))
    
    with open(output_file, 'w', encoding='utf-8') as f:
        f.writelines(results)

OCRライブラリの比較

ライブラリ精度速度日本語対応セットアップ
Tesseract良好やや複雑
EasyOCR良好簡単
PaddleOCR最高良好中程度

トラブルシューティング

よくあるエラーと対処法

import pytesseract
import sys

# Tesseractのパス設定(Windows)
if sys.platform == 'win32':
    pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

# 日本語フォント問題の対処
def check_japanese_support():
    try:
        langs = pytesseract.get_languages()
        return 'jpn' in langs
    except:
        return False

if not check_japanese_support():
    print("日本語パッケージがインストールされていません")

まとめ

PythonでのOCR実装は、適切なライブラリ選択と画像前処理により高精度な文字認識が可能です。用途に応じてTesseract、EasyOCR、PaddleOCRを使い分け、前処理技術を組み合わせることで実用的なシステムを構築できます。

特に日本語OCRでは、適切な言語設定と画像品質の向上が重要です。本記事のサンプルコードを参考に、あなたのプロジェクトに最適なOCRソリューションを実装してください。

参考文献

  • Tesseract公式ドキュメント
  • EasyOCR GitHub
  • OpenCV公式ドキュメント
  • PIL/Pillow公式ドキュメント

「らくらくPython塾」が切り開く「呪文コーディング」とは?

【革命的学習法】「らくらくPython塾」が切り開く、呪文コーディングという新時代のプログラミング習得術

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座

フリーランスボード

20万件以上の案件から、副業に最適なリモート・週3〜の案件を一括検索できるプラットフォーム。プロフィール登録でAIスカウトが自動的にマッチング案件を提案。市場統計や単価相場、エージェントの口コミも無料で閲覧可能なため、本業を続けながら効率的に高単価の副業案件を探せます。フリーランスボード

ITプロパートナーズ

週2〜3日から働ける柔軟な案件が業界トップクラスの豊富さを誇るフリーランスエージェント。エンド直契約のため高単価で、週3日稼働でも十分な報酬を得られます。リモートや時間フレキシブルな案件も多数。スタートアップ・ベンチャー中心で、トレンド技術を使った魅力的な案件が揃っています。専属エージェントが案件紹介から契約交渉までサポート。利用企業2,000社以上の実績。ITプロパートナーズ

Midworks 10,000件以上の案件を保有し、週3日〜・フルリモートなど柔軟な働き方に対応。高単価案件が豊富で、報酬保障制度(60%)や保険料負担(50%)など正社員並みの手厚い福利厚生が特徴。通勤交通費(月3万円)、スキルアップ費用(月1万円)の支給に加え、リロクラブ・freeeが無料利用可能。非公開案件80%以上、支払いサイト20日で安心して稼働できます。Midworks