diff --git a/agents/llama_vision/agent_vision_ocr.py b/agents/llama_vision/agent_vision_ocr.py index 9588a95..07b4a35 100644 --- a/agents/llama_vision/agent_vision_ocr.py +++ b/agents/llama_vision/agent_vision_ocr.py @@ -7,9 +7,9 @@ from pathlib import Path from ..base_agent import BaseAgent from ..utils.pipeline_logger import sauvegarder_donnees -from utils.ocr_cleaner import clean_text_with_profiles # AJOUT -from utils.ocr_utils import extraire_texte -from utils.image_preparer import prepare_image_for_llama_vision +from utils.ocr_avance.ocr_cleaner import clean_text_with_profiles +from utils.ocr_brut.ocr_utils import extraire_texte +from utils.ocr_avance.image_preparer import prepare_image_for_llama_vision logger = logging.getLogger("AgentVisionOCR") @@ -161,7 +161,9 @@ This prompt is designed to generalize across all web portals, technical forms, o # ✅ Étape 3 : Préparation de l'image pour le modèle Vision image_stem = Path(image_path).stem - vision_ready_path = os.path.join("debug_ocr", f"vision_ready_{image_stem}.png") + # Utiliser le nouveau chemin pour les résultats OCR avancé + os.makedirs("results/ocr_avance", exist_ok=True) + vision_ready_path = os.path.join("results/ocr_avance", f"vision_ready_{image_stem}.png") prepare_image_for_llama_vision(image_path, vision_ready_path) # Étape 4 : Appel au modèle avec image traitée @@ -175,6 +177,15 @@ This prompt is designed to generalize across all web portals, technical forms, o model_name = getattr(self.llm, "pipeline_normalized_name", getattr(self.llm, "modele", "llama3-vision-90b-instruct")) model_name = model_name.replace(".", "-").replace(":", "-").replace("_", "-") + + # Sauvegarde du résultat dans results/ocr_avance + try: + result_dir = "results/ocr_avance" + os.makedirs(result_dir, exist_ok=True) + with open(f"{result_dir}/ocr_{image_stem}.txt", "w", encoding="utf-8") as f: + f.write(cleaned_text) + except Exception as e: + logger.error(f"[OCR-LLM] Erreur sauvegarde texte: {e}") result = { "extracted_text": cleaned_text, diff --git a/docs/ARCHITECTURE_OCR.md b/docs/ARCHITECTURE_OCR.md new file mode 100644 index 0000000..1d5b8d8 --- /dev/null +++ b/docs/ARCHITECTURE_OCR.md @@ -0,0 +1,63 @@ +# Architecture OCR Réorganisée + +## Structure des Répertoires + +``` +project/ +│ +├── utils/ +│ ├── ocr_brut/ # OCR basique (Tesseract) +│ │ ├── ocr_utils.py # Fonctions d'extraction de texte +│ │ ├── ocr_preprocessor.py # Prétraitement d'images pour OCR +│ │ └── README.md # Documentation +│ │ +│ ├── ocr_avance/ # OCR avancé (Llama Vision) +│ │ ├── image_preparer.py # Préparation pour modèle Llama Vision +│ │ ├── ocr_cleaner.py # Nettoyage et amélioration du texte +│ │ ├── ocr_clean_dict.json # Dictionnaire de correction OCR +│ │ ├── hallucination_filter.json # Filtres pour hallucinations +│ │ ├── translation_clean_dict.json # Corrections pour traduction +│ │ └── README.md # Documentation +│ │ +│ └── __init__.py # Compatibilité avec imports existants +│ +├── agents/ +│ └── llama_vision/ +│ └── agent_vision_ocr.py # Agent principal utilisant les modules OCR +│ +├── results/ +│ ├── ocr_brut/ # Résultats OCR Tesseract +│ ├── ocr_avance/ # Résultats OCR Llama Vision +│ └── README.md # Documentation +│ +└── test_agent_ocr.py # Script de test principal +``` + +## Circuit de Traitement OCR + +1. **OCR Brut (Tesseract)** + - Sélection d'un profil de prétraitement (default, document, aggressive, clahe_high, invert_light) + - Prétraitement de l'image avec `ocr_preprocessor.py` + - Extraction du texte avec Tesseract via `ocr_utils.py` + - Sauvegarde des résultats dans `results/ocr_brut/` + +2. **OCR Avancé (Llama Vision)** + - Préparation de l'image pour le modèle avec `image_preparer.py` + - Envoi au modèle par l'agent `AgentVisionOCR` + - Nettoyage du texte extrait avec `ocr_cleaner.py` + - Sauvegarde des résultats dans `results/ocr_avance/` + +## Configuration Actuelle + +- **OCR Brut** : Profil "document" avec PSM=11, OEM=3 +- **OCR Avancé** : Modèle Llama Vision avec image redimensionnée à 672x672 + +## Tests + +Le script `test_agent_ocr.py` permet de tester l'ensemble du circuit avec une image de test. + +## Notes Importantes + +1. Les fichiers dans `utils/` servent uniquement à la compatibilité avec les imports existants +2. Les résultats sont stockés dans des répertoires séparés pour plus de clarté +3. Le répertoire `ocr_brut_test/` a été conservé pour des tests ultérieurs" \ No newline at end of file diff --git a/docs/RESUME_OCR.md b/docs/RESUME_OCR.md new file mode 100644 index 0000000..55fc799 --- /dev/null +++ b/docs/RESUME_OCR.md @@ -0,0 +1,54 @@ +# Résumé des Modifications du Système OCR + +## 1. Optimisation de l'OCR Brut (Tesseract) + +- **Configuration optimale** : + - Profil de prétraitement "document" adapté aux documents administratifs + - PSM=11 (sparse text) pour une meilleure extraction + - OEM=3 (mode par défaut) + +- **Simplification du code** : + - Suppression du redimensionnement redondant dans ocr_utils.py + - Uniformisation des chemins de sortie vers results/ocr_brut/ + - Amélioration de la gestion des erreurs + +## 2. Optimisation de l'OCR Avancé (Llama Vision) + +- **Préparation des images** : + - Standardisation de toutes les images à 672x672 pixels + - Conservation des proportions avec padding + - Sortie unique vers results/ocr_avance/ + +- **Nettoyage du texte** : + - Dictionnaires de nettoyage séparés par profil + - Système modulaire pour activer différents niveaux de correction + +## 3. Réorganisation de l'Architecture + +- **Séparation claire des modules** : + - OCR brut (Tesseract) dans utils/ocr_brut/ + - OCR avancé (Llama Vision) dans utils/ocr_avance/ + - Résultats dans results/ocr_brut/ et results/ocr_avance/ + +- **Documentation complète** : + - README pour chaque module + - Documentation ARCHITECTURE_OCR.md pour la vue d'ensemble + - Avertissements dans les fichiers obsolètes + +## 4. Tests et Compatibilité + +- **Maintien de la compatibilité** : + - Module utils/__init__.py pour assurer la transition + - Conservation des fichiers originaux avec avertissements + - Duplication des fichiers critiques dans utils/ocrbrut/ pour archivage + +- **Test agent_ocr.py** : + - Mise à jour pour utiliser les nouveaux chemins + - Création automatique des répertoires de résultats + - Affichage clair des chemins de sortie + +## 5. Prochaines Étapes Possibles + +- Suppression des fichiers obsolètes une fois la transition terminée +- Optimisation supplémentaire des profils de prétraitement +- Développement de nouveaux dictionnaires de correction \ No newline at end of file diff --git a/logs open_vpn b/logs open_vpn deleted file mode 100644 index 2e2356f..0000000 --- a/logs open_vpn +++ /dev/null @@ -1,155 +0,0 @@ -2025-05-07 08:46:02 OpenVPN 2.6.12 [git:v2.6.12/038a94bae57a446c] Windows [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [AEAD] [DCO] built on Jul 18 2024 -2025-05-07 08:46:02 Windows version 10.0 (Windows 10 or greater), amd64 executable -2025-05-07 08:46:02 library versions: OpenSSL 3.3.1 4 Jun 2024, LZO 2.10 -2025-05-07 08:46:02 DCO version: 1.2.1 -2025-05-07 08:46:02 TCP/UDP: Preserving recently used remote address: [AF_INET]37.71.248.18:1111 -2025-05-07 08:46:02 UDPv4 link local: (not bound) -2025-05-07 08:46:02 UDPv4 link remote: [AF_INET]37.71.248.18:1111 -2025-05-07 08:46:02 [vpn.cbao.fr] Peer Connection Initiated with [AF_INET]37.71.248.18:1111 -2025-05-07 08:46:04 open_tun -2025-05-07 08:46:04 tap-windows6 device [Connexion au réseau local] opened -2025-05-07 08:46:04 Set TAP-Windows TUN subnet mode network/local/netmask = 10.8.1.0/10.8.1.12/255.255.255.0 [SUCCEEDED] -2025-05-07 08:46:04 Notified TAP-Windows driver to set a DHCP IP/netmask of 10.8.1.12/255.255.255.0 on interface {2CCBC607-261F-452C-8E9E-893870FF0EAE} [DHCP-serv: 10.8.1.0, lease-time: 31536000] -2025-05-07 08:46:04 Successful ARP Flush on interface [6] {2CCBC607-261F-452C-8E9E-893870FF0EAE} -2025-05-07 08:46:04 IPv4 MTU set to 1500 on interface 6 using service -2025-05-07 08:46:09 Initialization Sequence Completed -2025-05-07 13:46:02 [vpn.cbao.fr] Inactivity timeout (--ping-restart), restarting -2025-05-07 13:46:02 SIGUSR1[soft,ping-restart] received, process restarting -2025-05-07 13:46:03 TCP/UDP: Preserving recently used remote address: [AF_INET]37.71.248.18:1111 -2025-05-07 13:46:03 UDPv4 link local: (not bound) -2025-05-07 13:46:03 UDPv4 link remote: [AF_INET]37.71.248.18:1111 -2025-05-07 13:46:05 [vpn.cbao.fr] Peer Connection Initiated with [AF_INET]37.71.248.18:1111 -2025-05-07 13:46:05 Preserving previous TUN/TAP instance: Connexion au réseau local -2025-05-07 13:46:05 Initialization Sequence Completed - - -dev tun -persist-tun -persist-key -data-ciphers AES-256-GCM:AES-256-CBC -data-ciphers-fallback AES-256-CBC -auth SHA256 -tls-client -client -resolv-retry infinite -remote 37.71.248.18 1111 udp4 -nobind -auth-user-pass -remote-cert-tls server -explicit-exit-notify -auth-nocache - ------BEGIN CERTIFICATE----- -MIIFBTCCA22gAwIBAgIIejdwM+00dLcwDQYJKoZIhvcNAQENBQAwWzEPMA0GA1UE -AxQGQ0FfVlBOMQswCQYDVQQGEwJGUjELMAkGA1UECBMCUE8xEjAQBgNVBAcTCVBl -cnBpZ25hbjENMAsGA1UEChMEQ0JBTzELMAkGA1UECxMCSVQwHhcNMjMwOTI5MDgx -MjM2WhcNMzMwOTI2MDgxMjM2WjBbMQ8wDQYDVQQDFAZDQV9WUE4xCzAJBgNVBAYT -AkZSMQswCQYDVQQIEwJQTzESMBAGA1UEBxMJUGVycGlnbmFuMQ0wCwYDVQQKEwRD -QkFPMQswCQYDVQQLEwJJVDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB -AKEpm8PH2IOLzN3YeTEw17uIxipWNXDhtG7eqWgzXrus2r4UGeH692zb59I5Krrn -4JIWIEvAxylDkGucaRj1fAB2kHfDoiT/13ivbje0PjDNlCYNScaN0brz5/Q+CHzn -eFA6LyjXXT/IdpduRW5pL5BsEFWGHwgCT68YG0rfIqRMfEqYHCwd16yH2kywNgqd -xC61CEmp3plIlng+8DYaSZ6Si4UoJ2xtYWzFyH0EafH2R9Vhd6xgw9HqVD5LkTNS -qj7imL2oqIcjx1xbBKi1jgXrv2emCYJKmU2yE4DGxnHIR4tHwgrw2rsA6EobTg3c -GM/DwW6IchRO6AgxThvpTglDerSI3eZ7P+ezCLu1DVzDSpC4bUp5ZFLB7tR01EqK -8LxFXdOFF9ynJNc5v6GjMF5yi1P65bYUG9gFDFF4NDx0ZYUTyNlyzAJgtuJPivRD -milL+MQYEsrA4cdc1Em9ssSK1AGwX/987DxlGM/KRilNLGGUpRVr0Bn7S3YJTEkk -IwIDAQABo4HMMIHJMB0GA1UdDgQWBBRNjdxfpJmKOG2uv4aIxfQDOSH3HzCBjAYD -VR0jBIGEMIGBgBRNjdxfpJmKOG2uv4aIxfQDOSH3H6FfpF0wWzEPMA0GA1UEAxQG -Q0FfVlBOMQswCQYDVQQGEwJGUjELMAkGA1UECBMCUE8xEjAQBgNVBAcTCVBlcnBp -Z25hbjENMAsGA1UEChMEQ0JBTzELMAkGA1UECxMCSVSCCHo3cDPtNHS3MAwGA1Ud -EwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBDQUAA4IBgQBqxHDMi2cn -UHc25JH1cEqOaiBfPKOyQuDXFeXQuc6lIuWOoiH4C/XGdMwxx9zP/WLpliVV4Wfq -PicjadSr6T77m5M55qPTFL6zG/oeKbHg+YHGIEdHMnMJPEon1nDx9lQsQFFoz9F/ -cAKMTGjxuCQbTqRnOf4mCSsi0vtn0SgYwcoNuJhAOpP4OJHu9nbUaLlx8VJMONku -4P2EHWro/2UEqldrp1xkH2kXwx7u4LJr916z6IHdfTu4pMkr+yTcrM0EM1aVdC08 -LqKj+WXcefcP6YZqajMgVbrAmq5JPLEmY4IiAl52b+kMEHp+mBfI+gvrJMMFZSz1 -/n1U949EVAafklr/FqD9HBlgesZtbNsflybhrFF4+CE9/9Mp9YZ/nvBGkxiaXSBA -Xr4Ftq48GMk/abpA3MCuH4UWlMO3RZLSD727umoOko2BPbNqMmkvEL4hTvCTliAr -ThV23Aasyc9zy977HivaLeJpsKNCMC+C83LYATMab7hhQ9c2BwIj4Fs= ------END CERTIFICATE----- - - ------BEGIN CERTIFICATE----- -MIIE1jCCAz6gAwIBAgIBETANBgkqhkiG9w0BAQsFADBbMQ8wDQYDVQQDFAZDQV9W -UE4xCzAJBgNVBAYTAkZSMQswCQYDVQQIEwJQTzESMBAGA1UEBxMJUGVycGlnbmFu -MQ0wCwYDVQQKEwRDQkFPMQswCQYDVQQLEwJJVDAeFw0yNTAzMTMwODI5NTJaFw0z -NTAzMTEwODI5NTJaMFoxDjAMBgNVBAMTBWZncmFzMQswCQYDVQQGEwJGUjELMAkG -A1UECBMCUE8xEjAQBgNVBAcTCVBlcnBpZ25hbjENMAsGA1UEChMEQ0JBTzELMAkG -A1UECxMCSVQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChIgHQkTkw -QePtBYlMc0lFtL1AUQSX3k7BV41BjDVIBo/k3BF/TkNzFm+dpFRVFsgWP62XNRXO -pIIujFVRNfmckjby8r3dcFdFVJjb0uimjAUxFf2tf5PPLgBojZX/6QVpcsApJQp9 -5D+oSVPudHqqCC2raBVW7ov9d9B+2GgBc9DwNd6gJplZNbUaxTgqwBrdC6sCO45/ -nzKdXSKan7cdfWY5N8VbYR89rzwdkBnoI7qp8csKONymcXIgypHjj1MC7LdvOAYW -6/PV8DJuzFneQmClRBRQBrCIu0lyGvAys5drdzllBllZ6xjm/cr9l4ShHGfGWtr1 -D7FaJ4umVyflAgMBAAGjggEkMIIBIDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAx -BglghkgBhvhCAQ0EJBYiT3BlblNTTCBHZW5lcmF0ZWQgVXNlciBDZXJ0aWZpY2F0 -ZTAdBgNVHQ4EFgQUmb4rkgQoE6tQM2FxUpnPPcuc1A4wgYwGA1UdIwSBhDCBgYAU -TY3cX6SZijhtrr+GiMX0Azkh9x+hX6RdMFsxDzANBgNVBAMUBkNBX1ZQTjELMAkG -A1UEBhMCRlIxCzAJBgNVBAgTAlBPMRIwEAYDVQQHEwlQZXJwaWduYW4xDTALBgNV -BAoTBENCQU8xCzAJBgNVBAsTAklUggh6N3Az7TR0tzATBgNVHSUEDDAKBggrBgEF -BQcDAjAQBgNVHREECTAHggVmZ3JhczANBgkqhkiG9w0BAQsFAAOCAYEAPhSURAu3 -XNV+gV5r6OGHXZMRmgUNjpXyJVo5MjSEgnBBqRwGfIcBd0VpNfZnrWqy1DMROGkI -g5aJ04Az5aD3CzUPfKcB8tAM4wT8+DteRZkGcMl7ZOqX++KoLsnA8AAejFinJ5FC -ZFnb16r/HpOw4tEZQfvGZ/FS8IyU8urLPk1IgOIKAqD0xZQNh73eeQnCIeS7RMpS -XVWDIGY/FlO+vBHqsusg3HlqRd4BQkxg22eKQFag01F9qCuu7VtRqiFH6G9RF0yU -UqkOCJU5HR+0CnGhKVM7SKIinGxPB1XskgrHdlpUckf4rlSDKxnX5OD+ooPz70Ex -L9hm0FmrHWVfCWjvZ0yDD8Sn2RslGT2XXZK57pRrh321SBFQDxIJgGlEmgBpjCaV -OqTw67AxG0ay9R2dQjVz1P/iTaiWLaeCQnMfNpFX0H9P+XPigw0xy6zepW6bxRDg -OYVgf+XV0yArTrnSJx9+/jW9xKRm+2DSRypxLWbZROJ5SErfpmGRX1NQ ------END CERTIFICATE----- - - ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQChIgHQkTkwQePt -BYlMc0lFtL1AUQSX3k7BV41BjDVIBo/k3BF/TkNzFm+dpFRVFsgWP62XNRXOpIIu -jFVRNfmckjby8r3dcFdFVJjb0uimjAUxFf2tf5PPLgBojZX/6QVpcsApJQp95D+o -SVPudHqqCC2raBVW7ov9d9B+2GgBc9DwNd6gJplZNbUaxTgqwBrdC6sCO45/nzKd -XSKan7cdfWY5N8VbYR89rzwdkBnoI7qp8csKONymcXIgypHjj1MC7LdvOAYW6/PV -8DJuzFneQmClRBRQBrCIu0lyGvAys5drdzllBllZ6xjm/cr9l4ShHGfGWtr1D7Fa -J4umVyflAgMBAAECggEBAIMkZWu1tmDTT8lJ9zv0nI8SEfF1vxJHibuMIVhW38qW -JKj0f30oWnchrIgWBdkW6JRLEWJ+fxgnBhkSeCHXlydaTUSgUe0XEMBJoPtQha9/ -SH5x0nxR2CAH5acyjQGySohPL5yNHCPoD/NMcvYhcPBQJbNay/trvR33VQbX5JZA -vMtZ822PcnklWUV+JUyk4McW8sAOw7UTCYaJMObwjAdkvi0cTpXOC6kp2Cn9leXW -Qvd6z26mXfk2gFgidkEKQkMNy5Np3/Nxssrth1+36WqQpMawZhWvrBtLnF21TUJW -AuwOtAmaaTver38X81doLVKNjr/oV4MTKmBC8iklLMECgYEA06Z/SlznvQaTolS2 -hs9fu7En5jEgt+6b/chUUpRePPsCMG44T7CJNGtJ6rNnaJ3pC+zmvVh+xO9Sk6IB -OWgyNJ5I/R5tXrSyTwSTJXoUEwq394mjG/b7nfcw0PrQumHbuFj/q6o3NIvNiDui -KtfnzX4tVftaKCeOcEtJKuaznlECgYEAwuWciItvbmqaRHHAme5/yYYED4BsRbCY -Kk8WOZ4NSGSfyMhonPXSpSuwF66yZmk864olSbWsTjXzGs13KX9NOeXCjUkohAY5 -tbps2CLoo/aDprjg4ZaWmXkFi6ceTzdoNIgSGf+Gro3P82fRPWLqcXfmWihPJh47 -3tvEVrKxZ1UCgYArgRrDD0u3CAYKpP0Lws57xxNbdpeyFwLLbIUgoEyqnjG6AL3k -a3YYZ0E/U/cagvLnN5/KJcmQ81x26iL0SN2hATQhi0KR5/SK13bjii9cJqTf5dO4 -KNFZi/jly9hhp0HBp9GN2KQWUfJCYXeY9N452Ai7lrnWbSMTI/Z7MgaTsQKBgQCA -GfOdPCjt5luniS0TAFQ13URl+/8ufzhE9t6g2GXao2jyy+cW4+yka+a+ajEQZzOH -jbGclTC/5232u/4K5IWZ/I631tIulPjxnatVFPzcaHd36iTFofkyvv0KIbomT0DK -5nUfaXjY2pVIY4CAXLfEBQ7/S2daopyviruuUJ2SUQKBgD1t4JloeG5yxXZmWLYY -QIXAJifNx3/U64mcXoRWZQukxMe3NB169f5Kbu2aAWS0Y+wa6WTFp+q6UwkHOqOm -dsFXc4IaYJICZQDpiuhqZi80c+TOJS5qUSHK5wKs4b1y2hxPeHNPoAWni+8292PB -ICZWzYno1a07gWGJeBhWSmsm ------END PRIVATE KEY----- - -key-direction 1 - -# -# 2048 bit OpenVPN static key -# ------BEGIN OpenVPN Static key V1----- -ad7131884e4148812622148d14af6d13 -6ea1e84f92132eb8e5a18c56d908ddf2 -97ae8b7b47d47e673b78b660dc91dace -7a97ce5934c20f49824bf8b7017b35ed -3a2fd7af967b2af243c1ca9482bb34d1 -6e93478e695b9c86b29b5b79f472e67c -740a09a341be6c2c1b13d4468e705768 -5dced700e2339a1e6f8b95165c869ec6 -9e24c48b4c9127ec99a9a9e7c7c63ac5 -aba05723e611ebbf76e343dcd1822b41 -245413c9398ee4b5d96087f3b360cb7b -046576c1a45c3a804e9b958439c7f4cd -2cc93666db736b8d9d62b522b61c6b01 -1d024d1b2c90fcee6c549a50e6e31062 -1e096b1d41ee6b22e53488c2d071429d -e42476b191c7f9767e157aa9e45798b2 ------END OpenVPN Static key V1----- - diff --git a/results/README.md b/results/README.md new file mode 100644 index 0000000..5dc1ec5 --- /dev/null +++ b/results/README.md @@ -0,0 +1,31 @@ +# Résultats des Traitements OCR + +Ce répertoire contient les résultats des différents traitements OCR effectués sur les images. + +## Structure + +- `ocr_brut/` : Résultats de l'OCR basique (Tesseract) + - Images prétraitées par les différents profils + - Fichiers texte extraits des images + +- `ocr_avance/` : Résultats de l'OCR avancé (Llama Vision) + - Images préparées pour le modèle Llama Vision + - Texte extrait par le modèle avec structure enrichie + +## Organisation des Fichiers + +### OCR Brut +- `preprocessed/[profil]/*.png` : Images prétraitées par profil +- `optimized_*.png` : Version finale prétraitée +- `ocr_*.txt` : Texte extrait par Tesseract + +### OCR Avancé +- `vision_ready_*.png` : Images préparées pour Llama Vision (672x672) +- `ocr_*.txt` : Texte structuré extrait par le modèle + +## Utilisation + +Ces résultats peuvent être utilisés pour : +- Comparer les performances des différentes méthodes d'OCR +- Vérifier les étapes de prétraitement des images +- Fournir des données d'entraînement pour améliorer les dictionnaires de correction" \ No newline at end of file diff --git a/results/ocr_avance/vision_ready_image_145435.png b/results/ocr_avance/vision_ready_image_145435.png new file mode 100644 index 0000000..2f99592 Binary files /dev/null and b/results/ocr_avance/vision_ready_image_145435.png differ diff --git a/results/ocr_brut/ocr_image_145435.png.txt b/results/ocr_brut/ocr_image_145435.png.txt new file mode 100644 index 0000000..402e620 --- /dev/null +++ b/results/ocr_brut/ocr_image_145435.png.txt @@ -0,0 +1,45 @@ += + +[e) + +“ + +giraudibrg-lsb.com/BRG-LAB/PAGE programmetssai/zE4AAHEVNGOAA + + BAGLAB C9 Béton C9 Fouméseu labo © Masse + +FAT :1 Essai au bleu de méthylène (MB) - NF EN 933-9 (02-2022) + +£E Victor + +Echantilion _n°25-00075 réceptionné le 02/04/2028 par BOLLÉE Victor - prélevé le 02/04/2025 por BOLLEE Victor, n° prélbvement : 2500078 + +Matériau Sable 0/2 C - CARRIERE ADCEG + +V HISTORIQUE + +72 + +[VU Essai [ve marée ][M For Uo |[v osservanons + +[ + +] + +NREGISTRER + +MPRMER + +le l'essai + +2025 + +(RE GIRAUD + +les statistiques + +lessai + +A + +impossible de trouver adresse IP du serveur de zk1.brg-lab.com. \ No newline at end of file diff --git a/results/ocr_brut/optimized_image_145435.png b/results/ocr_brut/optimized_image_145435.png new file mode 100644 index 0000000..8b4be0c Binary files /dev/null and b/results/ocr_brut/optimized_image_145435.png differ diff --git a/results/ocr_brut/preprocessed/document/optimized_image_145435.png b/results/ocr_brut/preprocessed/document/optimized_image_145435.png new file mode 100644 index 0000000..8b4be0c Binary files /dev/null and b/results/ocr_brut/preprocessed/document/optimized_image_145435.png differ diff --git a/test_agent_ocr.py b/test_agent_ocr.py index 62fa5ff..0907ec3 100644 --- a/test_agent_ocr.py +++ b/test_agent_ocr.py @@ -1,6 +1,11 @@ from agents.llama_vision.agent_vision_ocr import AgentVisionOCR from llm_classes.llama_vision import LlamaVision import json +import os + +# Créer les répertoires de résultats s'ils n'existent pas +os.makedirs("results/ocr_brut", exist_ok=True) +os.makedirs("results/ocr_avance", exist_ok=True) # Instanciation du modèle model = LlamaVision() @@ -17,3 +22,7 @@ image_path = "output/ticket_T11143/T11143_20250422_084617/attachments/image_1454 res = agent.executer(image_path) print(f"\n🔵 Résultat pour l'image {image_path}:") print(f"Texte extrait:\n{res['extracted_text']}\n") + +# Affichage des chemins de sortie +print(f"✅ Résultats OCR brut sauvegardés dans: results/ocr_brut/") +print(f"✅ Résultats OCR avancé sauvegardés dans: results/ocr_avance/") diff --git a/utils/__init__.py b/utils/__init__.py index fe0c32d..56314b8 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -5,5 +5,21 @@ Package utils contenant des utilitaires pour le traitement d'images et autres fo # Pas besoin de préfixer avec 'utils.' quand on est déjà dans le package from .image_dedup import filtrer_images_uniques +# Compatibilité avec les anciens imports après la réorganisation des fichiers OCR +from utils.ocr_brut import extraire_texte, extraire_texte_fr, preprocess_image, preprocess_image_with_profile, PREPROCESSING_PROFILES +from utils.ocr_avance import prepare_image_for_llama_vision, clean_text_with_profiles + # Exposer les fonctions principales -__all__ = ['filtrer_images_uniques'] \ No newline at end of file +__all__ = [ + # OCR Brut (Tesseract) + 'extraire_texte', + 'extraire_texte_fr', + 'preprocess_image', + 'preprocess_image_with_profile', + 'PREPROCESSING_PROFILES', + + # OCR Avancé (Llama Vision) + 'prepare_image_for_llama_vision', + 'clean_text_with_profiles', + 'filtrer_images_uniques' +] \ No newline at end of file diff --git a/utils/image_preparer.py b/utils/image_preparer.py index b0b1d25..4a81687 100644 --- a/utils/image_preparer.py +++ b/utils/image_preparer.py @@ -1,5 +1,12 @@ +""" +!!! FICHIER OBSOLÈTE !!! +Ce fichier est maintenu uniquement pour la compatibilité. +Veuillez utiliser les modules dans utils/ocr_avance/ à la place. +""" + from PIL import Image, ImageOps from pathlib import Path +import os BICUBIC = Image.Resampling.BICUBIC # Nouvelle façon d'accéder à BICUBIC diff --git a/utils/ocr_avance/README.md b/utils/ocr_avance/README.md new file mode 100644 index 0000000..f2a29bc --- /dev/null +++ b/utils/ocr_avance/README.md @@ -0,0 +1,32 @@ +# Module OCR Avancé (Llama Vision) + +Ce module contient les outils pour l'extraction de texte avancée utilisant le modèle Llama Vision. + +## Fichiers principaux + +- `image_preparer.py` : Prépare les images pour être utilisées avec le modèle Llama Vision +- `ocr_cleaner.py` : Nettoie et améliore le texte extrait par l'OCR +- Dictionnaires de nettoyage : + - `ocr_clean_dict.json` : Corrections de base pour l'OCR + - `hallucination_filter.json` : Filtres pour les hallucinations du modèle + - `translation_clean_dict.json` : Corrections pour les erreurs de traduction + +## Utilisation + +```python +from utils.ocr_avance import prepare_image_for_llama_vision, clean_text_with_profiles + +# Préparation d'une image pour Llama Vision +image_pretraitee = prepare_image_for_llama_vision("chemin/vers/image.jpg") + +# Nettoyage du texte extrait +texte_propre = clean_text_with_profiles(texte_brut, active_profiles=("ocr", "hallucination")) +``` + +## Résultats + +Les images prétraitées et les résultats de l'OCR sont sauvegardés dans le répertoire `results/ocr_avance/`. + +## Intégration avec l'agent + +Ce module est utilisé par l'agent `AgentVisionOCR` situé dans `agents/llama_vision/agent_vision_ocr.py`. \ No newline at end of file diff --git a/utils/ocr_avance/__init__.py b/utils/ocr_avance/__init__.py new file mode 100644 index 0000000..4d025ee --- /dev/null +++ b/utils/ocr_avance/__init__.py @@ -0,0 +1,8 @@ +from utils.ocr_avance.image_preparer import prepare_image_for_llama_vision +from utils.ocr_avance.ocr_cleaner import clean_text_with_profiles + +# Compatibilité rétroactive +__all__ = [ + 'prepare_image_for_llama_vision', + 'clean_text_with_profiles' +] \ No newline at end of file diff --git a/utils/ocr_avance/hallucination_filter.json b/utils/ocr_avance/hallucination_filter.json new file mode 100644 index 0000000..4e4ea0b --- /dev/null +++ b/utils/ocr_avance/hallucination_filter.json @@ -0,0 +1,10 @@ +{ + "The following information is fictional": "", + "This content is autogenerated and may not reflect reality": "", + "Lorem ipsum": "", + "As an AI language model": "", + "Note: The above is a sample output": "", + "BRG-LAB is a fictional laboratory": "BRG-LAB", + "This is a placeholder text": "" + } + \ No newline at end of file diff --git a/utils/ocr_avance/image_preparer.py b/utils/ocr_avance/image_preparer.py new file mode 100644 index 0000000..1c71381 --- /dev/null +++ b/utils/ocr_avance/image_preparer.py @@ -0,0 +1,32 @@ +from PIL import Image, ImageOps +from pathlib import Path +import os +from typing import Optional + +BICUBIC = Image.Resampling.BICUBIC # Nouvelle façon d'accéder à BICUBIC + +def prepare_image_for_llama_vision(input_path: str, output_path: Optional[str] = None, size=(672, 672)) -> str: + """Prépare une image pour être utilisée avec le modèle Llama Vision en la redimensionnant et en ajoutant du padding.""" + from PIL import ImageOps, Image + + # Si aucun chemin de sortie n'est spécifié, utiliser le répertoire par défaut + if output_path is None: + os.makedirs("results/ocr_avance", exist_ok=True) + image_name = Path(input_path).stem + output_path = f"results/ocr_avance/vision_ready_{image_name}.png" + + img = Image.open(input_path) + if img.mode != "RGB": + img = img.convert("RGB") + + # Redimensionne en conservant le ratio + img.thumbnail(size, Image.Resampling.BICUBIC) + + # Ajoute du padding pour obtenir exactement 672x672 + padded_img = Image.new("RGB", size, (255, 255, 255)) # fond blanc + offset = ((size[0] - img.width) // 2, (size[1] - img.height) // 2) + padded_img.paste(img, offset) + + padded_img.save(output_path, format="PNG", optimize=True) + return output_path + diff --git a/utils/ocr_avance/ocr_clean_dict.json b/utils/ocr_avance/ocr_clean_dict.json new file mode 100644 index 0000000..6a2699b --- /dev/null +++ b/utils/ocr_avance/ocr_clean_dict.json @@ -0,0 +1,8 @@ +{ + "zkt1.brg-lab.com": "zk1.brg-lab.com", + "ADEO": "ADCEG", + "ADEIG": "ADCEG", + "RA.Z.": "RAZ", + "NF EN 9933-9": "NF EN 933-9" + } + \ No newline at end of file diff --git a/utils/ocr_avance/ocr_cleaner.py b/utils/ocr_avance/ocr_cleaner.py new file mode 100644 index 0000000..a2925f8 --- /dev/null +++ b/utils/ocr_avance/ocr_cleaner.py @@ -0,0 +1,59 @@ +import json +from pathlib import Path + +# 🧩 Dictionnaires disponibles (clés = profils activables) +CLEAN_DICT_FILES = { + "ocr": "ocr_clean_dict.json", + "translation": "translation_clean_dict.json", + "hallucination": "hallucination_filter.json" +} + +# 📁 Chemin racine de tous les dictionnaires +BASE_PATH = Path(__file__).parent + +def load_cleaning_dict(path): + """Charge un dictionnaire de nettoyage JSON.""" + if not path.exists(): + return {} + with open(path, "r", encoding="utf-8") as f: + return json.load(f) + +def load_multiple_dicts(active_keys): + """Charge et fusionne plusieurs dictionnaires selon les profils sélectionnés.""" + merged_dict = {} + for key in active_keys: + filename = CLEAN_DICT_FILES.get(key) + if filename: + path = BASE_PATH / filename + data = load_cleaning_dict(path) + merged_dict.update(data) + return merged_dict + +def clean_ocr_text(text, cleaning_dict=None): + """Applique les corrections d’un dictionnaire sur un texte.""" + if cleaning_dict is None: + return text + for wrong, correct in cleaning_dict.items(): + text = text.replace(wrong, correct) + return text + +def clean_text_with_profiles(text, active_profiles=("ocr",)): + """ + Nettoie un texte avec un ou plusieurs profils activés. + Profils possibles : "ocr", "translation", "hallucination" + """ + cleaning_dict = load_multiple_dicts(active_profiles) + return clean_ocr_text(text, cleaning_dict) + +def add_to_cleaning_dict(wrong, correct, profile="ocr"): + """ + Ajoute une paire (erreur, correction) à un dictionnaire spécifique. + """ + filename = CLEAN_DICT_FILES.get(profile) + if not filename: + raise ValueError(f"Profil inconnu : {profile}") + path = BASE_PATH / filename + data = load_cleaning_dict(path) + data[wrong] = correct + with open(path, "w", encoding="utf-8") as f: + json.dump(data, f, indent=2, ensure_ascii=False) diff --git a/utils/ocr_avance/translation_clean_dict.json b/utils/ocr_avance/translation_clean_dict.json new file mode 100644 index 0000000..63508d2 --- /dev/null +++ b/utils/ocr_avance/translation_clean_dict.json @@ -0,0 +1,12 @@ +{ + "bearing capacity": "capacité portante", + "liquid limit": "limite de liquidité", + "air voids": "vides d'air", + "CEMENT": "ciment", + "AGGREGATE": "granulat", + "IT IS NOT RELEVANT": "NON APPLICABLE", + "SPECIMEN": "ÉCHANTILLON", + "trial mixture": "mélange d'essai", + "test": "essai" + } + \ No newline at end of file diff --git a/utils/ocr_brut/README.md b/utils/ocr_brut/README.md new file mode 100644 index 0000000..13fb551 --- /dev/null +++ b/utils/ocr_brut/README.md @@ -0,0 +1,30 @@ +# Module OCR Brut (Tesseract) + +Ce module contient les outils pour l'extraction de texte basique à partir d'images en utilisant Tesseract OCR. + +## Fichiers principaux + +- `ocr_utils.py` : Fonctions principales d'extraction de texte avec Tesseract +- `ocr_preprocessor.py` : Prétraitement d'images pour améliorer la qualité de l'OCR + +## Configuration par défaut + +- Profil de prétraitement : "document" +- PSM (Page Segmentation Mode) : 11 (Texte sparse) +- OEM (OCR Engine Mode) : 3 (par défaut) + +## Utilisation + +```python +from utils.ocr_brut import extraire_texte, extraire_texte_fr + +# OCR multilingue avec détection automatique +texte, image_optimisee = extraire_texte("chemin/vers/image.jpg") + +# OCR français optimisé +texte_fr = extraire_texte_fr("chemin/vers/image.jpg") +``` + +## Résultats + +Les résultats du prétraitement et de l'OCR sont sauvegardés dans le répertoire `results/ocr_brut/`. \ No newline at end of file diff --git a/utils/ocr_brut/__init__.py b/utils/ocr_brut/__init__.py new file mode 100644 index 0000000..e758d25 --- /dev/null +++ b/utils/ocr_brut/__init__.py @@ -0,0 +1,11 @@ +from utils.ocr_brut.ocr_utils import extraire_texte, extraire_texte_fr +from utils.ocr_brut.ocr_preprocessor import preprocess_image, preprocess_image_with_profile, PREPROCESSING_PROFILES + +# Compatibilité rétroactive +__all__ = [ + 'extraire_texte', + 'extraire_texte_fr', + 'preprocess_image', + 'preprocess_image_with_profile', + 'PREPROCESSING_PROFILES' +] \ No newline at end of file diff --git a/utils/ocr_brut/ocr_preprocessor.py b/utils/ocr_brut/ocr_preprocessor.py new file mode 100644 index 0000000..40493db --- /dev/null +++ b/utils/ocr_brut/ocr_preprocessor.py @@ -0,0 +1,159 @@ +# ocr_preprocessor.py + +import os +from PIL import Image, ImageEnhance +import cv2 +import numpy as np +import time + +# === 🎛️ PROFILS DE TRAITEMENT D'IMAGE OCR === +PREPROCESSING_PROFILES = { + "default": { + "resize_min_dim": 1000, # 📏 Si largeur/hauteur < 1000px, image agrandie proportionnellement + "enhance_contrast": True, # 🔆 Active l'amélioration du contraste + "contrast_factor": 1.2, # >1 = plus contrasté, typique : 1.2 à 1.8 + "enhance_sharpness": False, # 💥 Active la netteté + "sharpness_factor": 1.0, # >1 = plus net, typique : 1.2 à 2.0 + "apply_denoising": False, # 🚿 Réduction de bruit + "denoise_strength": { + "h": 0, # 0 à 15 : intensité du lissage luminance + "hColor": 0, # 0 à 15 : lissage chroma + "templateWindowSize": 7, # Taille du patch à comparer (typiquement 7) + "searchWindowSize": 21 # Zone autour du patch pour recherche (typiquement 21) + }, + "invert_colors": False, # ↕️ Inversion si texte clair sur fond sombre + "apply_clahe": False, # 📈 Égalisation du contraste local (utile en cas de zones très sombres/claires) + "save_debug_output": True, + "debug_output_dir": "results/ocr_brut/preprocessed" + }, + "aggressive": { + "resize_min_dim": 1400, + "enhance_contrast": True, + "contrast_factor": 1.8, + "enhance_sharpness": True, + "sharpness_factor": 1.5, + "apply_denoising": True, + "denoise_strength": { + "h": 10, + "hColor": 10, + "templateWindowSize": 7, + "searchWindowSize": 21 + }, + "invert_colors": False, + "apply_clahe": False, + "save_debug_output": True, + "debug_output_dir": "results/ocr_brut/preprocessed" + }, + "document": { + "resize_min_dim": 1100, + "enhance_contrast": True, + "contrast_factor": 1.2, + "enhance_sharpness": False, + "sharpness_factor": 1.0, + "apply_denoising": False, + "denoise_strength": {"h": 0, "hColor": 0, "templateWindowSize": 7, "searchWindowSize": 21}, + "invert_colors": False, + "apply_clahe": False, + "save_debug_output": True, + "debug_output_dir": "results/ocr_brut/preprocessed" + }, + "clahe_high": { + "resize_min_dim": 1200, + "enhance_contrast": True, + "contrast_factor": 1.4, + "enhance_sharpness": True, + "sharpness_factor": 1.3, + "apply_denoising": True, + "denoise_strength": { + "h": 7, + "hColor": 7, + "templateWindowSize": 7, # Taille du patch local utilisé + "searchWindowSize": 21 # Zone de recherche du filtre + }, + "invert_colors": False, + "apply_clahe": True, + "save_debug_output": True, + "debug_output_dir": "results/ocr_brut/preprocessed" + }, + "invert_light": { + "resize_min_dim": 1200, + "enhance_contrast": True, + "contrast_factor": 1.3, + "enhance_sharpness": True, + "sharpness_factor": 1.4, + "apply_denoising": False, + "invert_colors": True, + "apply_clahe": False, + "save_debug_output": True, + "debug_output_dir": "results/ocr_brut/preprocessed" + } +} + +def preprocess_image(image_path: str, **settings) -> Image.Image: + img = Image.open(image_path).convert("RGB") + base_name = os.path.basename(image_path) + + # Gestion des dossiers de debug + debug_dir = settings.get("debug_output_dir", "results/ocr_brut/preprocessed") + profile_name = settings.get("profile_name", "default") # Ajout du nom du profil + debug_profile_dir = os.path.join(debug_dir, profile_name) + os.makedirs(debug_profile_dir, exist_ok=True) + + # Redimensionnement + if settings.get("resize_min_dim", 0) > 0: + width, height = img.size + min_dim = min(width, height) + if min_dim < settings["resize_min_dim"]: + scale = settings["resize_min_dim"] / min_dim + new_size = (int(width * scale), int(height * scale)) + img = img.resize(new_size, Image.Resampling.BICUBIC) + + # Contraste + if settings.get("enhance_contrast", False): + enhancer = ImageEnhance.Contrast(img) + img = enhancer.enhance(settings.get("contrast_factor", 1.5)) + + # Netteté + if settings.get("enhance_sharpness", False): + enhancer = ImageEnhance.Sharpness(img) + img = enhancer.enhance(settings.get("sharpness_factor", 1.5)) + + # Convert to OpenCV image + img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) + + # Débruitage + if settings.get("apply_denoising", False): + strength = settings.get("denoise_strength", {}) + img_cv = cv2.fastNlMeansDenoisingColored( + img_cv, + None, + h=strength.get("h", 10), + hColor=strength.get("hColor", 10), + templateWindowSize=strength.get("templateWindowSize", 7), + searchWindowSize=strength.get("searchWindowSize", 21) + ) + + # CLAHE + if settings.get("apply_clahe", False): + lab = cv2.cvtColor(img_cv, cv2.COLOR_BGR2LAB) + l, a, b = cv2.split(lab) + clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) + cl = clahe.apply(l) + img_cv = cv2.merge((cl, a, b)) + img_cv = cv2.cvtColor(img_cv, cv2.COLOR_LAB2BGR) + + # Inversion + if settings.get("invert_colors", False): + img_cv = cv2.bitwise_not(img_cv) + + # Sauvegarde image prétraitée (debug) + if settings.get("save_debug_output", False): + debug_path = os.path.join(debug_profile_dir, f"optimized_{base_name}") + cv2.imwrite(debug_path, img_cv) + + return Image.fromarray(cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB)) + +def preprocess_image_with_profile(image_path: str, profile_name="default") -> Image.Image: + settings = PREPROCESSING_PROFILES[profile_name].copy() # On fait une copie pour ne pas modifier l'original + settings["profile_name"] = profile_name # On ajoute le nom du profil aux paramètres + return preprocess_image(image_path, **settings) diff --git a/utils/ocr_brut/ocr_utils.py b/utils/ocr_brut/ocr_utils.py new file mode 100644 index 0000000..04f1836 --- /dev/null +++ b/utils/ocr_brut/ocr_utils.py @@ -0,0 +1,103 @@ +import pytesseract +import cv2 +import numpy as np +import os +from pathlib import Path +from PIL import Image +from langdetect import detect +import re +from utils.ocr_brut.ocr_preprocessor import preprocess_image_with_profile + +# ⬇️ PARAMÈTRES CENTRAUX D'ACTIVATION ⬇️ +USE_PREPROCESSING = True # Active le prétraitement de l'image via ocr_preprocessor.py +USE_TEXT_CORRECTION = True # Corrige les mots tronqués après OCR +SAVE_DEBUG_OUTPUT = True # Sauvegarde image + texte dans debug_ocr/ +AUTO_DETECT_LANGUAGE = True # Détecte automatiquement la langue + +# Paramètres Tesseract optimaux selon tests +OCR_DEFAULT_PSM = 11 # Page segmentation mode 11 (sparse text) +OCR_DEFAULT_OEM = 3 # OCR Engine mode 3 (default, based on what is available) +OCR_DEFAULT_PROFILE = "document" # Profil de prétraitement optimal selon tests + +# Complétion de mots tronqués (rudimentaire mais utile) +def completer_mots_tronques(texte): + lignes = texte.splitlines() + lignes_corrigees = [] + for ligne in lignes: + if ligne.strip().endswith("-"): + ligne = ligne.strip()[:-1] + lignes_corrigees.append(ligne) + return "\n".join(lignes_corrigees) + +# Détection de langue automatique (si activée) +def detect_language_tesseract(image_cv): + try: + text_sample = pytesseract.image_to_string(image_cv, config="--psm 6") + lang = detect(text_sample) + return { + "fr": "fra", + "en": "eng" + }.get(lang, "fra+eng") + except: + return "fra+eng" + +# OCR principal +def extraire_texte(image_path, lang="auto"): + # Vérification de l'existence de l'image + if not os.path.exists(image_path): + print(f"[OCR] Image non trouvée: {image_path}") + return "", None + + # Prétraitement de l'image avec le profil optimal + if USE_PREPROCESSING: + img_optimized = preprocess_image_with_profile(image_path, profile_name=OCR_DEFAULT_PROFILE) + else: + img_optimized = Image.open(image_path) + + # Détection de langue + ocr_lang = lang + if lang == "auto" and AUTO_DETECT_LANGUAGE: + ocr_lang = detect_language_tesseract(img_optimized) + if ocr_lang == "auto": + ocr_lang = "fra+eng" + + # OCR avec paramètres optimaux + config = f"--psm {OCR_DEFAULT_PSM} --oem {OCR_DEFAULT_OEM} -l {ocr_lang}" + texte = pytesseract.image_to_string(img_optimized, config=config) + + # Correction des mots tronqués + if USE_TEXT_CORRECTION: + texte_corrige = completer_mots_tronques(texte) + if len(texte_corrige) >= len(texte) * 0.9: + texte = texte_corrige + + # Sauvegarde debug (si activée) + if SAVE_DEBUG_OUTPUT and texte: + try: + debug_dir = "results/ocr_brut" + os.makedirs(debug_dir, exist_ok=True) + image_name = Path(image_path).stem + + # Conversion si image PIL + if isinstance(img_optimized, Image.Image): + img_optimized = np.array(img_optimized) + if img_optimized.ndim == 3 and img_optimized.shape[2] == 3: + img_optimized = cv2.cvtColor(img_optimized, cv2.COLOR_RGB2BGR) + elif img_optimized.ndim == 3 and img_optimized.shape[2] == 4: + img_optimized = cv2.cvtColor(img_optimized, cv2.COLOR_RGBA2BGR) + + if isinstance(img_optimized, np.ndarray): + cv2.imwrite(f"{debug_dir}/optimized_{image_name}.png", img_optimized) + + with open(f"{debug_dir}/ocr_{image_name}.png.txt", "w", encoding="utf-8") as f: + f.write(texte) + + except Exception as e: + print(f"[OCR DEBUG] Erreur de sauvegarde debug: {e}") + + return texte, img_optimized + +# Raccourci rapide pour juste récupérer le texte en français +def extraire_texte_fr(image_path): + texte, _ = extraire_texte(image_path, lang="fra") + return texte diff --git a/utils/ocr_cleaner.py b/utils/ocr_cleaner.py index a2925f8..000a4c0 100644 --- a/utils/ocr_cleaner.py +++ b/utils/ocr_cleaner.py @@ -1,3 +1,9 @@ +""" +!!! FICHIER OBSOLÈTE !!! +Ce fichier est maintenu uniquement pour la compatibilité. +Veuillez utiliser les modules dans utils/ocr_avance/ à la place. +""" + import json from pathlib import Path @@ -30,7 +36,7 @@ def load_multiple_dicts(active_keys): return merged_dict def clean_ocr_text(text, cleaning_dict=None): - """Applique les corrections d’un dictionnaire sur un texte.""" + """Applique les corrections d'un dictionnaire sur un texte.""" if cleaning_dict is None: return text for wrong, correct in cleaning_dict.items(): diff --git a/utils/ocr_preprocessor.py b/utils/ocr_preprocessor.py index b361a43..35b2b62 100644 --- a/utils/ocr_preprocessor.py +++ b/utils/ocr_preprocessor.py @@ -1,3 +1,9 @@ +""" +!!! FICHIER OBSOLÈTE !!! +Ce fichier est maintenu uniquement pour la compatibilité. +Veuillez utiliser les modules dans utils/ocr_brut/ à la place. +""" + # ocr_preprocessor.py import os diff --git a/utils/ocr_utils.py b/utils/ocr_utils.py index ec3f301..49dfbfc 100644 --- a/utils/ocr_utils.py +++ b/utils/ocr_utils.py @@ -1,3 +1,9 @@ +""" +!!! FICHIER OBSOLÈTE !!! +Ce fichier est maintenu uniquement pour la compatibilité. +Veuillez utiliser les modules dans utils/ocr_brut/ à la place. +""" + import pytesseract import cv2 import numpy as np @@ -6,7 +12,7 @@ from pathlib import Path from PIL import Image from langdetect import detect import re -from utils.ocr_preprocessor import preprocess_image_with_profile +from utils.ocr_brut.ocr_preprocessor import preprocess_image_with_profile # ⬇️ PARAMÈTRES CENTRAUX D'ACTIVATION ⬇️ USE_PREPROCESSING = True # Active le prétraitement de l'image via ocr_preprocessor.py