RemiProAtos commited on
Commit
25af3cf
·
verified ·
1 Parent(s): 18572c8

replace pytesseract by PIL preprocessing & Mitral vision model

Browse files
Files changed (1) hide show
  1. app.py +53 -29
app.py CHANGED
@@ -1,8 +1,8 @@
 
1
  import gradio as gr
2
- import json
3
  import os
4
- from PIL import Image
5
- import pytesseract
6
  from mistralai.client import Mistral
7
  from dotenv import load_dotenv
8
  load_dotenv()
@@ -10,42 +10,66 @@ load_dotenv()
10
  client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
11
 
12
 
13
- def extract_info(image: Image.Image) -> str:
 
 
 
 
14
 
15
- # Convert to grayscale (makes it easier for OCR)
16
  image = image.convert("L")
17
- # Extract text from the image
18
- text = pytesseract.image_to_string(image)
19
-
20
- if not text.strip():
21
- return json.dumps({"error": "No text could be extracted from the image."}, indent=2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  response = client.chat.complete(
24
- model="mistral-small-latest",
25
  messages=[
26
  {
27
  "role": "system",
28
  "content": (
29
- """ tu es un assistant d'extraction de données.
30
- Extrait les informations demandées et renvoye un objet JSON propre.
31
- N'incluez aucune explication ni mise en forme Markdown.
32
- Formate le résultat en JSON simple en utilisant les clés suivantes uniquement.
33
-
34
-
35
- Nom
36
- Prénom
37
- Numéro de voie
38
- Type de voie (rue, route, avenue, etc...)
39
- Nom de la voie
40
- Complément du numéro de voie (bis, ter, ...)
41
- Complément d'adresse
42
- Code postale
43
- Ville
44
-
45
- n'incorpore aucune donné suplémentaire. si tu ne trouve pas la donnée indique n/a en valeur"""
46
  ),
47
  },
48
- {"role": "user", "content": f"Extract structured JSON from this OCR text:\n\n{text}"},
 
 
 
 
 
 
 
 
 
 
 
 
49
  ],
50
  )
51
 
 
1
+ import base64
2
  import gradio as gr
3
+ import io
4
  import os
5
+ from PIL import Image, ImageEnhance, ImageFilter
 
6
  from mistralai.client import Mistral
7
  from dotenv import load_dotenv
8
  load_dotenv()
 
10
  client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
11
 
12
 
13
+ def preprocess(image: Image.Image) -> Image.Image:
14
+ # Upscale if the image is small (photos taken from distance / low-res)
15
+ w, h = image.size
16
+ if w < 1500:
17
+ image = image.resize((w * 2, h * 2), Image.LANCZOS)
18
 
19
+ # Convert to grayscale removes colour noise irrelevant to text
20
  image = image.convert("L")
21
+
22
+ # Sharpen edges before contrast so fine strokes are preserved
23
+ image = image.filter(ImageFilter.SHARPEN)
24
+
25
+ # Boost contrast to make text pop against background
26
+ image = ImageEnhance.Contrast(image).enhance(2.0)
27
+
28
+ # Second sharpness pass to crisp up letter edges
29
+ image = ImageEnhance.Sharpness(image).enhance(2.0)
30
+
31
+ return image
32
+
33
+
34
+ def image_to_base64(image: Image.Image) -> str:
35
+ buffer = io.BytesIO()
36
+ image.save(buffer, format="JPEG", quality=95)
37
+ return base64.b64encode(buffer.getvalue()).decode("utf-8")
38
+
39
+
40
+ def extract_info(image: Image.Image) -> str:
41
+ image = preprocess(image)
42
+ b64 = image_to_base64(image)
43
 
44
  response = client.chat.complete(
45
+ model="pixtral-12b-2409",
46
  messages=[
47
  {
48
  "role": "system",
49
  "content": (
50
+ "Tu es un assistant d'extraction de données. "
51
+ "Extrait les informations demandées et renvoie un objet JSON propre. "
52
+ "N'inclue aucune explication ni mise en forme Markdown. "
53
+ "Formate le résultat en JSON simple en utilisant les clés suivantes uniquement: "
54
+ "Nom, Prénom, Numéro de voie, Type de voie, Nom de la voie, "
55
+ "Complément du numéro de voie, Complément d'adresse, Code postal, Ville. "
56
+ "N'incorpore aucune donnée supplémentaire. "
57
+ "Si tu ne trouves pas la donnée, indique n/a en valeur."
 
 
 
 
 
 
 
 
 
58
  ),
59
  },
60
+ {
61
+ "role": "user",
62
+ "content": [
63
+ {
64
+ "type": "image_url",
65
+ "image_url": f"data:image/jpeg;base64,{b64}",
66
+ },
67
+ {
68
+ "type": "text",
69
+ "text": "Extrait les informations structurées de ce document et renvoie uniquement le JSON.",
70
+ },
71
+ ],
72
+ },
73
  ],
74
  )
75