690530:1345 ADR-030-231-ocr-sandbox-two-step-flow #05
This commit is contained in:
@@ -4,10 +4,11 @@
|
||||
# Change Log:
|
||||
# - 2026-05-25: Initial Dockerfile สำหรับ PaddleOCR sidecar (port 8765)
|
||||
# - 2026-05-30: เปลี่ยนจาก PaddleOCR เป็น Tesseract OCR เพื่อความเข้ากันได้กับ CPU เก่า
|
||||
# - 2026-05-30: เพิ่ม system dependencies สำหรับ OpenCV (libsm6, libxext6, libxrender1, libfontconfig1, libx11-6)
|
||||
|
||||
FROM python:3.10-slim
|
||||
|
||||
# ติดตั้ง system dependencies สำหรับ PDF processing, Tesseract OCR และภาษาไทย
|
||||
# ติดตั้ง system dependencies สำหรับ PDF processing, Tesseract OCR, ภาษาไทย และ OpenCV
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libglib2.0-0 \
|
||||
libgl1 \
|
||||
@@ -16,6 +17,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-tha \
|
||||
tesseract-ocr-eng \
|
||||
libsm6 \
|
||||
libxext6 \
|
||||
libxrender1 \
|
||||
libfontconfig1 \
|
||||
libx11-6 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
# - 2026-05-25: Initial FastAPI server สำหรับ PaddleOCR sidecar
|
||||
# - 2026-05-30: เปลี่ยน lang='en' เป็น lang='ch' (CTJK) เพื่อรองรับภาษาไทย
|
||||
# - 2026-05-30: เปลี่ยนจาก PaddleOCR เป็น Tesseract OCR เพื่อความเข้ากันได้กับ CPU เก่า
|
||||
# - 2026-05-30: เพิ่ม OpenCV preprocessing (threshold, denoise) และ DPI 300 เพื่อเพิ่มความแม่นยำ
|
||||
|
||||
import os
|
||||
import logging
|
||||
@@ -15,6 +16,8 @@ from typing import Optional
|
||||
from PIL import Image
|
||||
import pytesseract
|
||||
import io
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from pydantic import BaseModel
|
||||
@@ -34,6 +37,26 @@ OCR_LANG = os.getenv("OCR_LANG", "tha+eng") # Tesseract language code (tha+eng
|
||||
logger.info(f"Tesseract OCR Sidecar initialized (lang={OCR_LANG})")
|
||||
|
||||
|
||||
def preprocess_image(pil_image: Image.Image) -> Image.Image:
|
||||
"""Preprocess image ด้วย OpenCV เพื่อเพิ่มความแม่นยำ OCR"""
|
||||
# แปลง PIL Image เป็น numpy array (OpenCV format)
|
||||
img_array = np.array(pil_image)
|
||||
|
||||
# แปลงเป็น grayscale
|
||||
gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
|
||||
|
||||
# Denoise ด้วย median blur
|
||||
denoised = cv2.medianBlur(gray, 3)
|
||||
|
||||
# Adaptive threshold เพื่อแยก background จาก text
|
||||
thresh = cv2.adaptiveThreshold(
|
||||
denoised, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2
|
||||
)
|
||||
|
||||
# แปลงกลับเป็น PIL Image
|
||||
return Image.fromarray(thresh)
|
||||
|
||||
|
||||
class OcrRequest(BaseModel):
|
||||
pdfPath: str
|
||||
maxPages: Optional[int] = None
|
||||
@@ -89,10 +112,14 @@ def ocr_extract(req: OcrRequest):
|
||||
ocr_text_parts = []
|
||||
for i in pages_to_process:
|
||||
page = doc[i]
|
||||
pix = page.get_pixmap(dpi=200)
|
||||
pix = page.get_pixmap(dpi=300) # เพิ่ม DPI เป็น 300 เพื่อความชัด
|
||||
img_bytes = pix.tobytes("png")
|
||||
img = Image.open(io.BytesIO(img_bytes))
|
||||
text = pytesseract.image_to_string(img, lang=OCR_LANG)
|
||||
|
||||
# Preprocess ด้วย OpenCV เพื่อเพิ่มความแม่นยำ
|
||||
processed_img = preprocess_image(img)
|
||||
|
||||
text = pytesseract.image_to_string(processed_img, lang=OCR_LANG)
|
||||
ocr_text_parts.append(text.strip())
|
||||
|
||||
ocr_text = "\n".join(ocr_text_parts).strip()
|
||||
|
||||
+2
@@ -2,6 +2,7 @@
|
||||
# Change Log:
|
||||
# - 2026-05-30: เปลี่ยนจาก PaddleOCR เป็น Tesseract OCR เพื่อความเข้ากันได้กับ CPU เก่า (ไม่ต้องการ AVX)
|
||||
# - 2026-05-30: ลบ paddlepaddle/paddleocr dependencies เนื่องจาก SIGILL บน CPU ที่ไม่รองรับ AVX
|
||||
# - 2026-05-30: เพิ่ม opencv-python สำหรับ image preprocessing (threshold, denoise) เพื่อเพิ่มความแม่นยำ OCR
|
||||
|
||||
numpy<2.0
|
||||
PyMuPDF==1.24.0
|
||||
@@ -12,3 +13,4 @@ python-multipart==0.0.9
|
||||
pythainlp==5.0.4
|
||||
httpx==0.27.0
|
||||
Pillow==10.0.0
|
||||
opencv-python==4.8.1.78
|
||||
|
||||
Reference in New Issue
Block a user