PaddleOCR 실행 전 이미지를 3채널 uint8로 표준화하여 Normalize IndexError 방지
This commit is contained in:
@@ -105,6 +105,41 @@ def preprocess_image_for_ocr(pil_img, page_idx=None):
|
||||
return Image.fromarray(img)
|
||||
|
||||
|
||||
def _to_rgb_uint8(img_np: np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
입력 이미지를 3채널 RGB, uint8 [0,255] 로 표준화
|
||||
허용 입력: HxW, HxWx1, HxWx3, HxWx4, float[0..1]/[0..255], int 등
|
||||
"""
|
||||
if img_np is None:
|
||||
raise ValueError("Input image is None")
|
||||
|
||||
# dtype/범위 표준화
|
||||
if img_np.dtype != np.uint8:
|
||||
arr = img_np.astype(np.float32)
|
||||
if arr.max() <= 1.0: # [0,1]로 보이면 스케일업
|
||||
arr *= 255.0
|
||||
arr = np.clip(arr, 0, 255).astype(np.uint8)
|
||||
img_np = arr
|
||||
|
||||
# 채널 표준화
|
||||
if img_np.ndim == 2: # HxW
|
||||
img_np = cv2.cvtColor(img_np, cv2.COLOR_GRAY2RGB)
|
||||
elif img_np.ndim == 3:
|
||||
h, w, c = img_np.shape
|
||||
if c == 1:
|
||||
img_np = cv2.cvtColor(img_np, cv2.COLOR_GRAY2RGB)
|
||||
elif c == 4:
|
||||
img_np = cv2.cvtColor(img_np, cv2.COLOR_RGBA2RGB)
|
||||
elif c == 3:
|
||||
pass # 그대로 사용
|
||||
else:
|
||||
raise ValueError(f"Unsupported channel count: {c}")
|
||||
else:
|
||||
raise ValueError(f"Unsupported ndim: {img_np.ndim}")
|
||||
|
||||
return img_np
|
||||
|
||||
|
||||
def extract_text_paddle_ocr(images):
|
||||
"""
|
||||
PaddleOCR를 사용하여 이미지에서 텍스트 추출 및 좌표 정보 반환
|
||||
@@ -121,8 +156,22 @@ def extract_text_paddle_ocr(images):
|
||||
print(f"[PaddleOCR] 페이지 {page_idx + 1} OCR로 텍스트 추출 중...")
|
||||
img_np = np.array(img)
|
||||
|
||||
if len(img_np.shape) == 2: # grayscale → RGB 변환
|
||||
img_np = cv2.cvtColor(img_np, cv2.COLOR_GRAY2RGB)
|
||||
# ✅ 채널/타입 표준화 (grayscale/rgba/float 등 대응)
|
||||
try:
|
||||
img_np = _to_rgb_uint8(img_np)
|
||||
except Exception as e:
|
||||
print(f"[PaddleOCR] 페이지 {page_idx + 1} 입력 표준화 실패: {e}")
|
||||
continue # 문제 페이지 스킵 후 다음 페이지 진행
|
||||
|
||||
# ✅ 과도한 해상도 안정화 (최대 변 4000px)
|
||||
h, w = img_np.shape[:2]
|
||||
max_side = max(h, w)
|
||||
max_side_limit = 4000
|
||||
if max_side > max_side_limit:
|
||||
scale = max_side_limit / max_side
|
||||
new_size = (int(w * scale), int(h * scale))
|
||||
img_np = cv2.resize(img_np, new_size, interpolation=cv2.INTER_AREA)
|
||||
print(f"[PaddleOCR] Resized to {img_np.shape[1]}x{img_np.shape[0]}")
|
||||
|
||||
results = ocr.predict(input=img_np)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user