Balde-maria2005 commited on
Commit
f42ecfa
·
verified ·
1 Parent(s): d9bff16

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -88
app.py CHANGED
@@ -1,122 +1,85 @@
 
1
  import gradio as gr
2
- import easyocr
3
- import numpy as np
4
- import cv2
5
  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. 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):
22
- raise ValueError("L'image semble floue. Veuillez fournir une image plus nette.")
23
- img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
24
- gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
25
- gray = cv2.equalizeHist(gray)
26
- blurred = cv2.GaussianBlur(gray, (3, 3), 0)
27
- coords = np.column_stack(np.where(blurred > 0))
28
- angle = cv2.minAreaRect(coords)[-1]
29
- angle = -(90 + angle) if angle < -45 else -angle
30
- (h, w) = blurred.shape
31
- M = cv2.getRotationMatrix2D((w // 2, h // 2), angle, 1.0)
32
- deskewed = cv2.warpAffine(blurred, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
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():
73
- match = re.search(pattern, text)
74
  if match:
75
- data[key] = match.group(2) if len(match.groups()) > 1 else match.group(1)
76
-
77
  return data
78
 
79
- # ---------- 6. Fonction principale ----------
80
- def analyser_carte(recto_img, verso_img):
81
  try:
82
- recto = preprocess_image(recto_img)
83
- verso = preprocess_image(verso_img)
84
-
85
- text_r = ocr_easyocr(recto)
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"
95
- "Merci de vérifier l'image ou d'en fournir une autre.",
96
- {}
97
- )
98
 
99
- champs = extract_fields(texte_total)
100
  return texte_total, champs
101
 
102
  except Exception as e:
103
- return f"Erreur : {str(e)}", {}
104
 
105
- # ---------- 7. Interface Gradio ----------
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 didentité 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
 
 
1
+ # app.py
2
  import gradio as gr
 
 
 
3
  from PIL import Image
4
+ import torch
5
+ from transformers import TrOCRProcessor, VisionEncoderDecoderModel
6
  import re
7
  import json
8
 
9
+ # Charger le modèle TrOCR
10
+ processor = TrOCRProcessor.from_pretrained("microsoft/trocr-base-stage1")
11
+ model = VisionEncoderDecoderModel.from_pretrained("microsoft/trocr-base-stage1")
12
+ model.eval()
13
 
14
+ def ocr_trocr(pil_image):
15
+ image = pil_image.convert("RGB")
16
+ pixel_values = processor(images=image, return_tensors="pt").pixel_values
17
+ with torch.no_grad():
18
+ generated_ids = model.generate(pixel_values)
19
+ text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
20
+ return text
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  def est_carte_identite_guineenne(texte):
23
+ texte = texte.upper().replace("’", "'")
24
  mots_cles = [
25
+ "CARTE", "IDENTITE", "GUINEE", "GUINEENNE", "REPUBLIQUE",
26
+ "CEDEAO", "GIN", "DATE DE NAISSANCE", "NUMERO", "MSPC",
27
+ "NOM", "PRENOM"
28
  ]
29
+ return sum(1 for mot in mots_cles if mot in texte) >= 3
 
30
 
31
+ def extraire_donnees(texte):
32
+ texte = texte.upper()
 
 
33
  patterns = {
34
+ "nom": r"NOM\s*[:\-]?\s*([A-Z\-]+)",
35
+ "prenom": r"PRENOM\s*[:\-]?\s*([A-Z\-]+)",
36
+ "sexe": r"SEXE\s*[:\-]?\s*([MF])",
37
+ "taille": r"TAILLE\s*[:\-]?\s*([0-9,.]+\s?M)",
38
+ "nationalite": r"NATIONALITE\s*[:\-]?\s*([A-Z]+)",
39
  "date_naissance": r"(\d{2}\s(?:JAN|FEB|MAR|APR|MAI|JUN|JUL|AOU|SEP|OCT|NOV|DEC)\s\d{4})",
40
+ "numero_id": r"(\d{16})",
41
+ "nin": r"(\d{15})",
42
+ "date_emission": r"DATE D['’]?EMISSION\s*[:\-]?\s*(\d{2}\s\w+\s\d{4})",
43
+ "date_expiration": r"DATE D['’]?EXPIRATION\s*[:\-]?\s*(\d{2}\s\w+\s\d{4})",
44
+ "lieu": r"CONAKRY|KANKAN|NZEREKORE|LABE|KINDIA|BOKE|FARANAH"
 
 
45
  }
46
+ data = {}
47
  for key, pattern in patterns.items():
48
+ match = re.search(pattern, texte)
49
  if match:
50
+ data[key] = match.group(1)
 
51
  return data
52
 
53
+ def analyse_carte(recto_img, verso_img):
 
54
  try:
55
+ texte_recto = ocr_trocr(recto_img)
56
+ texte_verso = ocr_trocr(verso_img)
57
+ texte_total = texte_recto + "\n" + texte_verso
 
 
 
 
 
 
58
 
59
  if not est_carte_identite_guineenne(texte_total):
60
+ return " Ce document ne semble pas être une carte d'identité guinéenne.", {}
 
 
 
 
61
 
62
+ champs = extraire_donnees(texte_total)
63
  return texte_total, champs
64
 
65
  except Exception as e:
66
+ return f"Erreur de traitement : {str(e)}", {}
67
 
 
68
  interface = gr.Interface(
69
+ fn=analyse_carte,
70
  inputs=[
71
+ gr.Image(type="pil", label="Image Recto"),
72
+ gr.Image(type="pil", label="Image Verso")
73
  ],
74
  outputs=[
75
+ gr.Textbox(label="Texte OCR extrait"),
76
+ gr.JSON(label="Champs structurés extraits")
77
  ],
78
+ title="OCRIA - Lecture intelligente de carte d'identité guinéenne",
79
+ description="Scannez les deux faces d'une carte d'identité guinéenne. Le système vérifie et extrait automatiquement les informations clés."
 
80
  )
81
 
82
+ if __name__ == "__main__":
83
+ interface.launch()
84
+
85