182 lines
6.6 KiB
Python
182 lines
6.6 KiB
Python
import os
|
|
import sys
|
|
import pandas as pd
|
|
from paddleocr import PaddleOCR
|
|
from PIL import Image
|
|
from tqdm import tqdm
|
|
import logging
|
|
import argparse
|
|
|
|
# Konfiguriere das Logging
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(levelname)s - %(message)s',
|
|
handlers=[
|
|
logging.StreamHandler(sys.stdout),
|
|
logging.FileHandler('ocr_comparison.log')
|
|
]
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Pfad zum debug_images-Verzeichnis
|
|
DEBUG_IMAGES_DIR = 'debug_images'
|
|
|
|
# Bilddateinamen, die verglichen werden sollen
|
|
IMAGE_FILES = {
|
|
'original': 'original.png',
|
|
'original_compressed': 'original_compressed.jpg',
|
|
'denoised': 'denoised.png'
|
|
}
|
|
|
|
# Initialisiere PaddleOCR
|
|
logger.info("Initialisiere PaddleOCR...")
|
|
ocr = PaddleOCR(
|
|
use_angle_cls=True,
|
|
lang='en',
|
|
det_db_thresh=0.3,
|
|
det_db_box_thresh=0.3,
|
|
det_db_unclip_ratio=2.0,
|
|
rec_char_type='en',
|
|
det_limit_side_len=960,
|
|
det_limit_type='max',
|
|
use_dilation=True,
|
|
det_db_score_mode='fast',
|
|
show_log=False # Setze auf False, um die PaddleOCR-Logs zu unterdrücken
|
|
)
|
|
|
|
def perform_ocr(image_path):
|
|
"""Führt OCR auf dem gegebenen Bildpfad durch und gibt die Ergebnisse zurück."""
|
|
try:
|
|
result = ocr.ocr(image_path, rec=True, cls=True)
|
|
if not result:
|
|
return {'num_texts': 0, 'avg_confidence': 0.0}
|
|
|
|
num_texts = 0
|
|
total_confidence = 0.0
|
|
|
|
for line in result:
|
|
for word in line:
|
|
text, confidence = word[1]
|
|
num_texts += 1
|
|
total_confidence += float(confidence)
|
|
|
|
avg_confidence = total_confidence / num_texts if num_texts > 0 else 0.0
|
|
return {'num_texts': num_texts, 'avg_confidence': avg_confidence}
|
|
except Exception as e:
|
|
logger.error(f"Fehler bei OCR für Bild {image_path}: {e}")
|
|
return {'num_texts': 0, 'avg_confidence': 0.0}
|
|
|
|
def compare_ocr_results(results):
|
|
"""
|
|
Vergleicht die OCR-Ergebnisse zwischen den verschiedenen Bildversionen.
|
|
Gibt an, welche Version tendenziell bessere Ergebnisse liefert.
|
|
"""
|
|
comparison = {}
|
|
versions = list(IMAGE_FILES.keys())
|
|
|
|
for version in versions:
|
|
comparison[version] = {
|
|
'num_texts': results[version]['num_texts'],
|
|
'avg_confidence': results[version]['avg_confidence']
|
|
}
|
|
|
|
# Entscheidung basierend auf den Metriken
|
|
# Kriterien können angepasst werden
|
|
# Hier priorisieren wir höhere avg_confidence und mehr num_texts
|
|
best_version = None
|
|
best_score = -1
|
|
|
|
for version in versions:
|
|
score = comparison[version]['avg_confidence'] + (comparison[version]['num_texts'] / 100) # Gewichtung anpassen
|
|
if score > best_score:
|
|
best_score = score
|
|
best_version = version
|
|
|
|
return best_version, comparison
|
|
|
|
def parse_arguments():
|
|
"""Parst Kommandozeilenargumente."""
|
|
parser = argparse.ArgumentParser(description='Vergleicht OCR-Ergebnisse verschiedener Bildversionen in debug_images-Ordnern.')
|
|
parser.add_argument(
|
|
'folders',
|
|
nargs='?',
|
|
default=None,
|
|
help='Durch Kommata getrennte Liste von Ordner-IDs (max. 10), z.B. 20250112_121938_2172d7b3,20250112_122055_ea9e2a72,20250130_182431_2498fcba'
|
|
)
|
|
return parser.parse_args()
|
|
|
|
def main():
|
|
args = parse_arguments()
|
|
|
|
if args.folders:
|
|
# Verarbeite die durch Kommata getrennte Liste von Ordner-IDs
|
|
folder_ids = [folder.strip() for folder in args.folders.split(',')]
|
|
if len(folder_ids) > 10:
|
|
logger.warning("Mehr als 10 Ordner-IDs angegeben. Es werden nur die ersten 10 verarbeitet.")
|
|
folder_ids = folder_ids[:10]
|
|
else:
|
|
# Automatisch die ersten 10 Ordner im debug_images-Verzeichnis auswählen
|
|
if not os.path.exists(DEBUG_IMAGES_DIR):
|
|
logger.error(f"Verzeichnis '{DEBUG_IMAGES_DIR}' existiert nicht.")
|
|
sys.exit(1)
|
|
|
|
# Sammle alle Unterverzeichnisse und wähle die ersten 10 aus
|
|
subdirs = [d for d in os.listdir(DEBUG_IMAGES_DIR) if os.path.isdir(os.path.join(DEBUG_IMAGES_DIR, d))]
|
|
folder_ids = subdirs[:10]
|
|
logger.info(f"Keine Ordner-IDs angegeben. Es werden die ersten {len(folder_ids)} Ordner verarbeitet.")
|
|
|
|
logger.info(f"Starte die OCR-Vergleichsanalyse für {len(folder_ids)} Ordner: {', '.join(folder_ids)}")
|
|
|
|
# Liste zum Speichern der Ergebnisse
|
|
results_list = []
|
|
|
|
for subdir in tqdm(folder_ids, desc="Verarbeitung der Ordner"):
|
|
subdir_path = os.path.join(DEBUG_IMAGES_DIR, subdir)
|
|
if not os.path.isdir(subdir_path):
|
|
logger.warning(f"Ordner '{subdir}' existiert nicht im '{DEBUG_IMAGES_DIR}' Verzeichnis.")
|
|
continue
|
|
|
|
ocr_results = {}
|
|
for version, filename in IMAGE_FILES.items():
|
|
image_path = os.path.join(subdir_path, filename)
|
|
if not os.path.isfile(image_path):
|
|
logger.warning(f"Bild '{filename}' fehlt im Ordner '{subdir}'.")
|
|
ocr_results[version] = {'num_texts': 0, 'avg_confidence': 0.0}
|
|
continue
|
|
ocr_result = perform_ocr(image_path)
|
|
ocr_results[version] = ocr_result
|
|
|
|
best_version, comparison = compare_ocr_results(ocr_results)
|
|
|
|
results_list.append({
|
|
'folder_id': subdir,
|
|
'best_version': best_version,
|
|
'original_num_texts': ocr_results['original']['num_texts'],
|
|
'original_avg_confidence': ocr_results['original']['avg_confidence'],
|
|
'original_compressed_num_texts': ocr_results['original_compressed']['num_texts'],
|
|
'original_compressed_avg_confidence': ocr_results['original_compressed']['avg_confidence'],
|
|
'denoised_num_texts': ocr_results['denoised']['num_texts'],
|
|
'denoised_avg_confidence': ocr_results['denoised']['avg_confidence']
|
|
})
|
|
|
|
if not results_list:
|
|
logger.warning("Keine Ergebnisse zum Speichern vorhanden.")
|
|
sys.exit(0)
|
|
|
|
# Erstelle einen DataFrame und speichere ihn als CSV
|
|
output_csv = 'ocr_comparison_results.csv'
|
|
df = pd.DataFrame(results_list)
|
|
df.to_csv(output_csv, index=False)
|
|
logger.info(f"OCR-Vergleichsanalyse abgeschlossen. Ergebnisse gespeichert in '{output_csv}'.")
|
|
|
|
# Optional: Statistiken anzeigen
|
|
total = len(df)
|
|
best_counts = df['best_version'].value_counts()
|
|
logger.info("Zusammenfassung der besten Versionen:")
|
|
for version, count in best_counts.items():
|
|
percentage = (count / total) * 100 if total > 0 else 0
|
|
logger.info(f"{version}: {count} von {total} ({percentage:.2f}%)")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|