IMG_Worker/modules/onnx_ocr_module/test/compare_results.py

244 lines
9.5 KiB
Python

# -*- coding: utf-8 -*-
"""
ONNX vs PaddlePaddle 상세 텍스트 결과 비교
"""
import os
import sys
import time
import logging
from typing import Dict, List
# 모듈 경로 추가
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
# 가짜 GPU 매니저 및 로거 클래스
class MockGPUManager:
def __init__(self, can_use_cuda=True):
self.can_use_cuda = can_use_cuda
class MockLogger:
def log(self, message: str, level=logging.INFO, exc_info=False):
pass # 조용한 로거
def compare_ocr_results():
"""ONNX와 PaddlePaddle OCR 결과 상세 비교"""
print("🔍 ONNX vs PaddlePaddle 텍스트 감지 결과 상세 비교")
print("=" * 70)
test_image = os.path.join(os.path.dirname(__file__), "1.jpg")
if not os.path.exists(test_image):
print(f"❌ 테스트 이미지를 찾을 수 없습니다: {test_image}")
return
logger = MockLogger()
gpu_manager = MockGPUManager(can_use_cuda=True)
# 1. ONNX CPU 결과 수집
print("\n🔧 ONNX CPU 결과 수집 중...")
try:
from onnx_ocr_module import ONNXOCRModule
ocr_onnx_cpu = ONNXOCRModule(
logger=logger,
gpu_manager=gpu_manager,
execution_provider='cpu'
)
start_time = time.time()
onnx_cpu_results = ocr_onnx_cpu.detect_text(test_image)
onnx_cpu_time = (time.time() - start_time) * 1000
print(f"✅ ONNX CPU: {len(onnx_cpu_results)}개 텍스트, {onnx_cpu_time:.1f}ms")
except Exception as e:
print(f"❌ ONNX CPU 실패: {e}")
onnx_cpu_results = []
onnx_cpu_time = 0
# 2. ONNX CUDA 결과 수집
print("\n🚀 ONNX CUDA 결과 수집 중...")
try:
ocr_onnx_cuda = ONNXOCRModule(
logger=logger,
gpu_manager=gpu_manager,
execution_provider='cuda'
)
start_time = time.time()
onnx_cuda_results = ocr_onnx_cuda.detect_text(test_image)
onnx_cuda_time = (time.time() - start_time) * 1000
print(f"✅ ONNX CUDA: {len(onnx_cuda_results)}개 텍스트, {onnx_cuda_time:.1f}ms")
except Exception as e:
print(f"❌ ONNX CUDA 실패: {e}")
onnx_cuda_results = []
onnx_cuda_time = 0
# 3. PaddlePaddle CPU 결과 수집
print("\n🐼 PaddlePaddle CPU 결과 수집 중...")
try:
from paddleocr import PaddleOCR
ocr_paddle_cpu = PaddleOCR(use_gpu=False, use_angle_cls=True, lang='ch', show_log=False)
start_time = time.time()
paddle_cpu_raw = ocr_paddle_cpu.ocr(test_image)
paddle_cpu_time = (time.time() - start_time) * 1000
# PaddleOCR 결과 파싱
paddle_cpu_results = []
if paddle_cpu_raw and paddle_cpu_raw[0]:
for i, line in enumerate(paddle_cpu_raw[0]):
if len(line) >= 2:
polygon = line[0]
text = line[1][0]
confidence = line[1][1]
# 바운딩 박스 계산
import numpy as np
import cv2
polygon_np = np.array(polygon, dtype=np.int32)
x, y, w, h = cv2.boundingRect(polygon_np)
paddle_cpu_results.append({
'text': text,
'confidence': confidence,
'polygon': polygon,
'bbox': (x, y, w, h),
'method': 'paddle'
})
print(f"✅ Paddle CPU: {len(paddle_cpu_results)}개 텍스트, {paddle_cpu_time:.1f}ms")
except Exception as e:
print(f"❌ PaddlePaddle CPU 실패: {e}")
paddle_cpu_results = []
paddle_cpu_time = 0
# 4. PaddlePaddle CUDA 결과 수집
print("\n🐼🚀 PaddlePaddle CUDA 결과 수집 중...")
try:
ocr_paddle_cuda = PaddleOCR(use_gpu=True, use_angle_cls=True, lang='ch', show_log=False)
start_time = time.time()
paddle_cuda_raw = ocr_paddle_cuda.ocr(test_image)
paddle_cuda_time = (time.time() - start_time) * 1000
# PaddleOCR 결과 파싱
paddle_cuda_results = []
if paddle_cuda_raw and paddle_cuda_raw[0]:
for i, line in enumerate(paddle_cuda_raw[0]):
if len(line) >= 2:
polygon = line[0]
text = line[1][0]
confidence = line[1][1]
# 바운딩 박스 계산
import numpy as np
import cv2
polygon_np = np.array(polygon, dtype=np.int32)
x, y, w, h = cv2.boundingRect(polygon_np)
paddle_cuda_results.append({
'text': text,
'confidence': confidence,
'polygon': polygon,
'bbox': (x, y, w, h),
'method': 'paddle'
})
print(f"✅ Paddle CUDA: {len(paddle_cuda_results)}개 텍스트, {paddle_cuda_time:.1f}ms")
except Exception as e:
print(f"❌ PaddlePaddle CUDA 실패: {e}")
paddle_cuda_results = []
paddle_cuda_time = 0
# 5. 결과 상세 비교
print("\n" + "="*70)
print("📊 텍스트 감지 결과 상세 비교")
print("="*70)
# 성능 비교
print(f"\n⚡ 성능 비교:")
print(f"{'모델':<20} {'시간(ms)':<12} {'텍스트 수':<10}")
print("-" * 42)
print(f"{'ONNX CPU':<20} {onnx_cpu_time:<12.1f} {len(onnx_cpu_results):<10}")
print(f"{'ONNX CUDA':<20} {onnx_cuda_time:<12.1f} {len(onnx_cuda_results):<10}")
print(f"{'Paddle CPU':<20} {paddle_cpu_time:<12.1f} {len(paddle_cpu_results):<10}")
print(f"{'Paddle CUDA':<20} {paddle_cuda_time:<12.1f} {len(paddle_cuda_results):<10}")
# 텍스트 내용 비교 (ONNX CUDA vs Paddle CUDA)
print(f"\n📝 텍스트 내용 상세 비교 (ONNX CUDA vs Paddle CUDA):")
print("-" * 70)
if onnx_cuda_results and paddle_cuda_results:
print(f"\n🔧 ONNX CUDA 감지 텍스트 ({len(onnx_cuda_results)}개):")
for i, result in enumerate(onnx_cuda_results, 1):
text = result['text']
conf = result['confidence']
bbox = result['bbox']
print(f" {i:2d}. '{text}' (신뢰도: {conf:.3f}, 위치: {bbox})")
print(f"\n🐼 Paddle CUDA 감지 텍스트 ({len(paddle_cuda_results)}개):")
for i, result in enumerate(paddle_cuda_results, 1):
text = result['text']
conf = result['confidence']
bbox = result['bbox']
print(f" {i:2d}. '{text}' (신뢰도: {conf:.3f}, 위치: {bbox})")
# 텍스트 세트 비교
onnx_texts = set(r['text'] for r in onnx_cuda_results if r['text'].strip())
paddle_texts = set(r['text'] for r in paddle_cuda_results if r['text'].strip())
# ONNX에만 있는 텍스트
onnx_only = onnx_texts - paddle_texts
if onnx_only:
print(f"\n🆕 ONNX에서만 발견된 텍스트 ({len(onnx_only)}개):")
for text in sorted(onnx_only):
# 해당 텍스트의 신뢰도와 위치 찾기
for result in onnx_cuda_results:
if result['text'] == text:
print(f" - '{text}' (신뢰도: {result['confidence']:.3f}, 위치: {result['bbox']})")
break
# Paddle에만 있는 텍스트
paddle_only = paddle_texts - onnx_texts
if paddle_only:
print(f"\n🆕 Paddle에서만 발견된 텍스트 ({len(paddle_only)}개):")
for text in sorted(paddle_only):
# 해당 텍스트의 신뢰도와 위치 찾기
for result in paddle_cuda_results:
if result['text'] == text:
print(f" - '{text}' (신뢰도: {result['confidence']:.3f}, 위치: {result['bbox']})")
break
# 공통 텍스트
common_texts = onnx_texts & paddle_texts
if common_texts:
print(f"\n🤝 공통으로 발견된 텍스트 ({len(common_texts)}개):")
for text in sorted(common_texts):
# 신뢰도 비교
onnx_conf = next((r['confidence'] for r in onnx_cuda_results if r['text'] == text), 0)
paddle_conf = next((r['confidence'] for r in paddle_cuda_results if r['text'] == text), 0)
conf_diff = onnx_conf - paddle_conf
conf_symbol = "🟢" if conf_diff > 0.1 else "🔴" if conf_diff < -0.1 else "🟡"
print(f" {conf_symbol} '{text}' | ONNX: {onnx_conf:.3f} vs Paddle: {paddle_conf:.3f} (차이: {conf_diff:+.3f})")
print("\n🎯 분석 결론:")
if len(onnx_cuda_results) > len(paddle_cuda_results):
diff = len(onnx_cuda_results) - len(paddle_cuda_results)
print(f"✅ ONNX가 {diff}개 더 많은 텍스트를 감지했습니다!")
elif len(paddle_cuda_results) > len(onnx_cuda_results):
diff = len(paddle_cuda_results) - len(onnx_cuda_results)
print(f"⚠️ Paddle이 {diff}개 더 많은 텍스트를 감지했습니다.")
else:
print("🟰 두 모델이 동일한 수의 텍스트를 감지했습니다.")
if __name__ == "__main__":
compare_ocr_results()