kebson commited on
Commit
9697857
·
verified ·
1 Parent(s): ecf1403

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -26
app.py CHANGED
@@ -4,12 +4,11 @@ import unicodedata
4
  from paddleocr import PaddleOCR
5
 
6
  # =================================================
7
- # OCR Paddle
8
  # =================================================
9
  ocr = PaddleOCR(
10
  lang="fr",
11
- use_textline_orientation=True,
12
- show_log=False
13
  )
14
 
15
  # =================================================
@@ -23,7 +22,6 @@ def normalize(text: str) -> str:
23
 
24
  # =================================================
25
  # Titres possibles de la colonne 2
26
- # (casse ignorée automatiquement)
27
  # =================================================
28
  COL_TITLES = {
29
  "designation",
@@ -33,7 +31,7 @@ COL_TITLES = {
33
  }
34
 
35
  # =================================================
36
- # Mots à ignorer absolument
37
  # =================================================
38
  IGNORE_KEYWORDS = {
39
  "prix", "ht", "htva", "tva", "ttc",
@@ -50,14 +48,14 @@ def extract_second_column(image):
50
  img = np.array(image)
51
 
52
  # -------------------------------------------------
53
- # 0. Rotation automatique si image couchée
54
  # -------------------------------------------------
55
  h, w = img.shape[:2]
56
  if w > h:
57
  img = np.rot90(img, 1)
58
 
59
  # -------------------------------------------------
60
- # 1. OCR
61
  # -------------------------------------------------
62
  result = ocr.predict(img)
63
  if not result:
@@ -82,7 +80,7 @@ def extract_second_column(image):
82
  return "Pas assez de texte exploitable."
83
 
84
  # -------------------------------------------------
85
- # 2. Détection robuste du X de la colonne 2
86
  # -------------------------------------------------
87
  col_x = None
88
  for text, x, y in blocks:
@@ -98,7 +96,7 @@ def extract_second_column(image):
98
  return "Titre de la colonne cible non détecté."
99
 
100
  # -------------------------------------------------
101
- # 3. Sélection des blocs de la colonne 2
102
  # -------------------------------------------------
103
  X_THRESHOLD = 55
104
  column_blocks = [
@@ -110,12 +108,12 @@ def extract_second_column(image):
110
  return "Colonne détectée mais vide."
111
 
112
  # -------------------------------------------------
113
- # 4. Tri vertical (haut → bas)
114
  # -------------------------------------------------
115
  column_blocks.sort(key=lambda e: e[2])
116
 
117
  # -------------------------------------------------
118
- # 5. Fusion intelligente des lignes OCR
119
  # -------------------------------------------------
120
  merged = []
121
  current = ""
@@ -141,25 +139,18 @@ def extract_second_column(image):
141
  merged.append(current.strip())
142
 
143
  # -------------------------------------------------
144
- # 6. Nettoyage final des cellules texte
145
  # -------------------------------------------------
146
  final = []
147
  for line in merged:
148
  nt = normalize(line)
149
 
150
- # ignorer le titre de colonne
151
  if nt in COL_TITLES:
152
  continue
153
-
154
- # longueur minimale
155
  if len(nt) < 5:
156
  continue
157
-
158
- # ignorer lignes trop numériques
159
  if sum(c.isdigit() for c in line) > len(line) / 3:
160
  continue
161
-
162
- # règle métier : commence par majuscule
163
  if not line[0].isupper():
164
  continue
165
 
@@ -168,13 +159,10 @@ def extract_second_column(image):
168
  if not final:
169
  return "Aucune cellule texte valide trouvée."
170
 
171
- # -------------------------------------------------
172
- # 7. Résultat numéroté
173
- # -------------------------------------------------
174
  return "\n".join(f"{i+1}. {line}" for i, line in enumerate(final))
175
 
176
  # =================================================
177
- # Interface Gradio (Hugging Face)
178
  # =================================================
179
  demo = gr.Interface(
180
  fn=extract_second_column,
@@ -182,9 +170,8 @@ demo = gr.Interface(
182
  outputs=gr.Textbox(label="Contenu de la colonne 2"),
183
  title="Extraction fiable de la colonne 2",
184
  description=(
185
- "Extraction automatique et adaptative de la deuxième colonne "
186
- "(Désignation, DESIGNATIONS, Description, Description des services) "
187
- "à partir de tableaux scannés."
188
  )
189
  )
190
 
 
4
  from paddleocr import PaddleOCR
5
 
6
  # =================================================
7
+ # OCR Paddle (HF compatible)
8
  # =================================================
9
  ocr = PaddleOCR(
10
  lang="fr",
11
+ use_textline_orientation=True
 
12
  )
13
 
14
  # =================================================
 
22
 
23
  # =================================================
24
  # Titres possibles de la colonne 2
 
25
  # =================================================
26
  COL_TITLES = {
27
  "designation",
 
31
  }
32
 
33
  # =================================================
34
+ # Mots à ignorer
35
  # =================================================
36
  IGNORE_KEYWORDS = {
37
  "prix", "ht", "htva", "tva", "ttc",
 
48
  img = np.array(image)
49
 
50
  # -------------------------------------------------
51
+ # Rotation automatique si image couchée
52
  # -------------------------------------------------
53
  h, w = img.shape[:2]
54
  if w > h:
55
  img = np.rot90(img, 1)
56
 
57
  # -------------------------------------------------
58
+ # OCR
59
  # -------------------------------------------------
60
  result = ocr.predict(img)
61
  if not result:
 
80
  return "Pas assez de texte exploitable."
81
 
82
  # -------------------------------------------------
83
+ # Détection du X de la colonne 2 via le titre
84
  # -------------------------------------------------
85
  col_x = None
86
  for text, x, y in blocks:
 
96
  return "Titre de la colonne cible non détecté."
97
 
98
  # -------------------------------------------------
99
+ # Sélection des blocs de la colonne
100
  # -------------------------------------------------
101
  X_THRESHOLD = 55
102
  column_blocks = [
 
108
  return "Colonne détectée mais vide."
109
 
110
  # -------------------------------------------------
111
+ # Tri vertical
112
  # -------------------------------------------------
113
  column_blocks.sort(key=lambda e: e[2])
114
 
115
  # -------------------------------------------------
116
+ # Fusion intelligente des lignes OCR
117
  # -------------------------------------------------
118
  merged = []
119
  current = ""
 
139
  merged.append(current.strip())
140
 
141
  # -------------------------------------------------
142
+ # Nettoyage final
143
  # -------------------------------------------------
144
  final = []
145
  for line in merged:
146
  nt = normalize(line)
147
 
 
148
  if nt in COL_TITLES:
149
  continue
 
 
150
  if len(nt) < 5:
151
  continue
 
 
152
  if sum(c.isdigit() for c in line) > len(line) / 3:
153
  continue
 
 
154
  if not line[0].isupper():
155
  continue
156
 
 
159
  if not final:
160
  return "Aucune cellule texte valide trouvée."
161
 
 
 
 
162
  return "\n".join(f"{i+1}. {line}" for i, line in enumerate(final))
163
 
164
  # =================================================
165
+ # Interface Gradio
166
  # =================================================
167
  demo = gr.Interface(
168
  fn=extract_second_column,
 
170
  outputs=gr.Textbox(label="Contenu de la colonne 2"),
171
  title="Extraction fiable de la colonne 2",
172
  description=(
173
+ "Extraction adaptative de la deuxième colonne "
174
+ "(Désignation, DESIGNATIONS, Description, Description des services)."
 
175
  )
176
  )
177