Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -6,16 +6,16 @@ from PIL import Image
|
|
6 |
import re
|
7 |
import json
|
8 |
|
9 |
-
# Initialisation EasyOCR
|
10 |
reader = easyocr.Reader(['fr', 'en'], gpu=False)
|
11 |
|
12 |
-
# ---------- 1.
|
13 |
def est_image_floue(image_np, seuil=100):
|
14 |
gris = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
|
15 |
variance = cv2.Laplacian(gris, cv2.CV_64F).var()
|
16 |
return variance < seuil
|
17 |
|
18 |
-
# ---------- 2. Prétraitement
|
19 |
def preprocess_image(pil_image):
|
20 |
img = np.array(pil_image)
|
21 |
if est_image_floue(img):
|
@@ -33,40 +33,40 @@ def preprocess_image(pil_image):
|
|
33 |
thresh = cv2.adaptiveThreshold(deskewed, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
|
34 |
return thresh
|
35 |
|
36 |
-
# ---------- 3. OCR ----------
|
37 |
def ocr_easyocr(image_np):
|
38 |
results = reader.readtext(image_np)
|
39 |
texte = "\n".join([text[1] for text in results])
|
40 |
return texte
|
41 |
|
42 |
-
# ---------- 4.
|
43 |
def est_carte_identite_guineenne(texte):
|
44 |
texte = texte.upper()
|
45 |
mots_cles = [
|
46 |
-
"CARTE
|
47 |
-
"
|
48 |
-
"SEXE", "DATE DE NAISSANCE", "NUMERO", "EXPIRATION", "EMISSION"
|
49 |
]
|
50 |
-
|
|
|
51 |
|
52 |
-
# ---------- 5. Extraction
|
53 |
def extract_fields(text):
|
54 |
data = {}
|
55 |
text = text.upper()
|
56 |
patterns = {
|
57 |
-
"nom": r"(NOM)[\s
|
58 |
-
"prenom": r"(PRENOM)[\s
|
59 |
-
"sexe": r"(SEXE)[\s
|
60 |
-
"taille": r"(TAILLE)[\s
|
61 |
-
"nationalite": r"(NATIONALITE)[\s
|
62 |
"date_naissance": r"(\d{2}\s(?:JAN|FEB|MAR|APR|MAI|JUN|JUL|AOU|SEP|OCT|NOV|DEC)\s\d{4})",
|
63 |
"numero_id": r"([0-9]{16})",
|
64 |
"code_pays": r"\bGIN\b",
|
65 |
"nin": r"\b[0-9]{15}\b",
|
66 |
-
"lieu_naissance": r"(NAISSANCE|LIEU)[\s
|
67 |
-
"prefecture": r"(PREFECTURE)[\s
|
68 |
-
"date_emission": r"(EMISSION)[\s
|
69 |
-
"date_expiration": r"(EXPIRATION)[\s
|
70 |
}
|
71 |
|
72 |
for key, pattern in patterns.items():
|
@@ -86,6 +86,9 @@ def analyser_carte(recto_img, verso_img):
|
|
86 |
text_v = ocr_easyocr(verso)
|
87 |
texte_total = text_r + "\n" + text_v
|
88 |
|
|
|
|
|
|
|
89 |
if not est_carte_identite_guineenne(texte_total):
|
90 |
return (
|
91 |
"**Alerte :** Le document fourni ne semble **pas être une carte d'identité guinéenne**.\n"
|
@@ -103,16 +106,17 @@ def analyser_carte(recto_img, verso_img):
|
|
103 |
interface = gr.Interface(
|
104 |
fn=analyser_carte,
|
105 |
inputs=[
|
106 |
-
gr.Image(type="pil", label="Recto
|
107 |
-
gr.Image(type="pil", label="Verso
|
108 |
],
|
109 |
outputs=[
|
110 |
-
gr.Textbox(label="Texte brut
|
111 |
gr.JSON(label="Champs extraits")
|
112 |
],
|
113 |
-
title="OCRIA -
|
114 |
-
description="Téléversez le recto et le verso d'une carte
|
115 |
theme="soft"
|
116 |
)
|
117 |
|
118 |
interface.launch()
|
|
|
|
6 |
import re
|
7 |
import json
|
8 |
|
9 |
+
# Initialisation EasyOCR
|
10 |
reader = easyocr.Reader(['fr', 'en'], gpu=False)
|
11 |
|
12 |
+
# ---------- 1. Vérifie si l'image est floue ----------
|
13 |
def est_image_floue(image_np, seuil=100):
|
14 |
gris = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
|
15 |
variance = cv2.Laplacian(gris, cv2.CV_64F).var()
|
16 |
return variance < seuil
|
17 |
|
18 |
+
# ---------- 2. Prétraitement image ----------
|
19 |
def preprocess_image(pil_image):
|
20 |
img = np.array(pil_image)
|
21 |
if est_image_floue(img):
|
|
|
33 |
thresh = cv2.adaptiveThreshold(deskewed, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
|
34 |
return thresh
|
35 |
|
36 |
+
# ---------- 3. OCR avec EasyOCR ----------
|
37 |
def ocr_easyocr(image_np):
|
38 |
results = reader.readtext(image_np)
|
39 |
texte = "\n".join([text[1] for text in results])
|
40 |
return texte
|
41 |
|
42 |
+
# ---------- 4. Vérification carte guinéenne (plus tolérante) ----------
|
43 |
def est_carte_identite_guineenne(texte):
|
44 |
texte = texte.upper()
|
45 |
mots_cles = [
|
46 |
+
"CARTE", "IDENTITE", "GUINÉE", "GUINEENNE", "CAMARA", "SALEMATOU",
|
47 |
+
"DATE DE NAISSANCE", "NUMERO D'IDENTITE", "REPUBLIQUE", "CEDEAO", "GIN", "MSPC", "NATIONALITE"
|
|
|
48 |
]
|
49 |
+
mots_trouves = sum(1 for mot in mots_cles if mot in texte)
|
50 |
+
return mots_trouves >= 3 # Seuil minimal : 3 mots-clés détectés
|
51 |
|
52 |
+
# ---------- 5. Extraction des champs ----------
|
53 |
def extract_fields(text):
|
54 |
data = {}
|
55 |
text = text.upper()
|
56 |
patterns = {
|
57 |
+
"nom": r"(NOM)[\s:/]+([A-Z\-]+)",
|
58 |
+
"prenom": r"(PRENOM)[\s:/]+([A-Z\-]+)",
|
59 |
+
"sexe": r"(SEXE)[\s:/]+([FM])",
|
60 |
+
"taille": r"(TAILLE)[\s:/]+([0-9,]+\s?M)",
|
61 |
+
"nationalite": r"(NATIONALITE)[\s:/]+([A-Z]+)",
|
62 |
"date_naissance": r"(\d{2}\s(?:JAN|FEB|MAR|APR|MAI|JUN|JUL|AOU|SEP|OCT|NOV|DEC)\s\d{4})",
|
63 |
"numero_id": r"([0-9]{16})",
|
64 |
"code_pays": r"\bGIN\b",
|
65 |
"nin": r"\b[0-9]{15}\b",
|
66 |
+
"lieu_naissance": r"(NAISSANCE|LIEU)[\s:/]+([A-Z\-]+)",
|
67 |
+
"prefecture": r"(PREFECTURE)[\s:/]+([A-Z\-]+)",
|
68 |
+
"date_emission": r"(EMISSION)[\s:/]+(\d{2}\s\w+\s\d{4})",
|
69 |
+
"date_expiration": r"(EXPIRATION)[\s:/]+(\d{2}\s\w+\s\d{4})",
|
70 |
}
|
71 |
|
72 |
for key, pattern in patterns.items():
|
|
|
86 |
text_v = ocr_easyocr(verso)
|
87 |
texte_total = text_r + "\n" + text_v
|
88 |
|
89 |
+
# Debug : Affiche le texte extrait pour diagnostic
|
90 |
+
# print("Texte OCR :\n", texte_total)
|
91 |
+
|
92 |
if not est_carte_identite_guineenne(texte_total):
|
93 |
return (
|
94 |
"**Alerte :** Le document fourni ne semble **pas être une carte d'identité guinéenne**.\n"
|
|
|
106 |
interface = gr.Interface(
|
107 |
fn=analyser_carte,
|
108 |
inputs=[
|
109 |
+
gr.Image(type="pil", label="Recto de la carte"),
|
110 |
+
gr.Image(type="pil", label="Verso de la carte")
|
111 |
],
|
112 |
outputs=[
|
113 |
+
gr.Textbox(label="Texte OCR brut"),
|
114 |
gr.JSON(label="Champs extraits")
|
115 |
],
|
116 |
+
title="OCRIA - Analyse intelligente de carte d’identité guinéenne",
|
117 |
+
description="Téléversez le recto et le verso d'une carte. Le système vérifie l’authenticité, détecte les flous et extrait automatiquement les informations clés.",
|
118 |
theme="soft"
|
119 |
)
|
120 |
|
121 |
interface.launch()
|
122 |
+
|