File size: 4,435 Bytes
baba668
 
 
 
 
 
 
 
 
 
 
 
693596e
baba668
 
693596e
baba668
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
693596e
 
 
 
baba668
 
 
 
693596e
 
 
a60e50a
 
baba668
 
 
 
 
 
 
a60e50a
 
baba668
693596e
 
 
baba668
 
693596e
 
 
baba668
 
693596e
 
 
 
 
 
baba668
693596e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import os

from dotenv import load_dotenv

load_dotenv(override=True)

import io
import os
from typing import Union

import easyocr
import firebase_admin
import gradio as gr
from firebase_admin import credentials, firestore
from loguru import logger
from PIL import Image
from thefuzz import fuzz

from processor import ImageHandler, PreprocessingConfig, ProcessedImage


class EasyOCRReader:
    def __init__(self):
        self.reader = easyocr.Reader(["fr", "en"], gpu=False)
        self.process = ImageHandler()
        self.config = PreprocessingConfig()

    def chat(self, image):
        processed: ProcessedImage = self.process.preprocess_image(image, self.config)
        image = Image.fromarray(processed.image)
        # Convert image to bytes
        img_byte_arr = io.BytesIO()
        image.save(img_byte_arr, format="PNG")
        img_byte_arr = img_byte_arr.getvalue()

        # Call readtext with image bytes
        texts = self.reader.readtext(img_byte_arr, detail=0)
        logger.info(" ".join(texts))
        return texts


class FirebaseConnector:
    def get_config(self):
        return {
            "type": os.getenv("type"),
            "project_id": os.getenv("project_id"),
            "private_key_id": os.getenv("private_key_id"),
            "private_key": os.getenv("private_key").replace("\\n", "\n"),
            "client_email": os.getenv("client_email"),
            "client_id": os.getenv("client_id"),
            "auth_uri": os.getenv("auth_uri"),
            "token_uri": os.getenv("token_uri"),
            "auth_provider_x509_cert_url": os.getenv("auth_provider_x509_cert_url"),
            "client_x509_cert_url": os.getenv("client_x509_cert_url"),
            "universe_domain": os.getenv("universe_domain"),
        }

    def __init__(self):
        # print(os.environ)
        firebase_config = self.get_config()
        cred = credentials.Certificate(firebase_config)
        firebase_admin.initialize_app(cred)
        self.db = firestore.client()

    def add(self, ocr: str, key: str):
        doc_ref = self.db.collection("id-card").document(key)
        if doc_ref.get().exists:
            raise ValueError(f"Document with key {key} already exists.")
        return self.db.collection("id-card").add({"ocr": ocr}, document_id=key)


def search_element(words: list[str], target: str, thr: float = 60):
    scores = list(map(lambda x: fuzz.partial_ratio(x, target), words))
    word_scores = [(w, s) for w, s in zip(words, scores) if s >= thr]
    return word_scores


class VoterCardVerifier:
    def __init__(self):
        self.db = FirebaseConnector()
        self.ocr_engine = EasyOCRReader()

    def verify_card(self, image: Union[str, Image.Image], card_number, thr: float = 60):
        # Convertir l'image pour Groq
        if isinstance(image, str):
            image = Image.open(image)

        # Préparer la requête pour le modèle et l'appeler
        ocr_data = self.ocr_engine.chat(image)

        score1 = search_element(ocr_data, "camer", thr)
        score2 = search_element(ocr_data, card_number, thr)

        ocr_data = score1 + score2
        logger.info(str(ocr_data))

        # valider les entrées
        is_valid = len(score1) and len(score2)

        if is_valid:
            # Sauvegarder dans Firebase
            self.save_card_number(ocr_data, card_number)
            return "Your ID Card have been recorded, thank you !!!"
        else:
            return "Numéro de carte non trouvé sur l'image"

    def save_card_number(self, ocr_data, card_number):
        return self.db.add(str(ocr_data), str(card_number))


# Interface Gradio
def create_interface():
    verifier = VoterCardVerifier()

    def process(image, card_number: str):
        if not card_number.strip():
            return "Veuillez entrer un numéro de carte"
        return verifier.verify_card(image, card_number)

    interface = gr.Interface(
        fn=process,
        inputs=[
            gr.Image(type="pil", label="Image de la carte d'électeur"),
            gr.Textbox(label="Numéro de carte"),
        ],
        outputs=gr.Textbox(label="Résultat"),
        title="Vérification de Carte d'Électeur",
        description="Uploadez une image de votre carte d'électeur et entrez son numéro pour vérification",
    )

    return interface


if __name__ == "__main__":

    # Créer et lancer l'interface
    demo = create_interface()
    demo.launch()