imperiusrex commited on
Commit
c5a297b
·
verified ·
1 Parent(s): 1005475

Upload 4 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ captcha_recognition_model_char.keras filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+
3
+ import gradio as gr
4
+ import tensorflow as tf
5
+ import numpy as np
6
+ from PIL import Image
7
+ import json
8
+ import os
9
+
10
+ # --- 1. Define int_to_char mapping and decode_prediction function ---
11
+ # This part is crucial and should accurately reflect what your model was trained on.
12
+ # We'll load int_to_char from the JSON file that was pushed to the repo.
13
+
14
+ # Get the directory where app.py is located.
15
+ # When deployed on Hugging Face Spaces, your model files will typically be in the
16
+ # same root directory as app.py if it's cloned from a model repo.
17
+ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
18
+
19
+ # Define paths to model and mapping relative to CURRENT_DIR
20
+ MODEL_PATH = os.path.join(CURRENT_DIR, "captcha_recognition_model_char.keras")
21
+ INT_TO_CHAR_PATH = os.path.join(CURRENT_DIR, "int_to_char.json")
22
+
23
+ try:
24
+ # Load the int_to_char mapping from the JSON file
25
+ with open(INT_TO_CHAR_PATH, "r") as f:
26
+ str_int_to_char_mapping = json.load(f)
27
+ # Convert keys back to integers as expected by decode_prediction
28
+ int_to_char = {int(k): v for k, v in str_int_to_char_mapping.items()}
29
+ print(f"int_to_char mapping loaded successfully from {INT_TO_CHAR_PATH}")
30
+ except Exception as e:
31
+ print(f"Error loading int_to_char.json: {e}")
32
+ # Fallback to a default or raise an error if the mapping is critical
33
+ # For robust deployment, ensure int_to_char.json is always present and valid.
34
+ int_to_char = {i: chr(i + ord('A')) for i in range(26)} # Example placeholder
35
+ int_to_char.update({26 + i: str(i) for i in range(10)})
36
+ int_to_char.update({36 + i: chr(i + ord('a')) for i in range(26)})
37
+ int_to_char[0] = '<pad>' # Assuming 0 is pad
38
+ print("Using a default placeholder for int_to_char due to error. Please verify original mapping.")
39
+
40
+ # Assuming fixed_solution_length is known from your model design.
41
+ # You might need to retrieve this from your model's config if it's not truly fixed,
42
+ # but for most captcha models, it's a fixed value.
43
+ fixed_solution_length = 5 # <--- IMPORTANT: Adjust this if your actual fixed_solution_length is different!
44
+
45
+ def decode_prediction(prediction_output, int_to_char_mapping):
46
+ """Decodes the integer-encoded prediction back to a string."""
47
+ # The prediction output from a Keras model is a NumPy array.
48
+ # It usually has shape (batch_size, fixed_solution_length, num_classes)
49
+ predicted_indices = np.argmax(prediction_output, axis=-1)[0] # Get indices for the first image in batch
50
+
51
+ # Convert indices back to characters using the mapping
52
+ predicted_chars = [int_to_char_mapping.get(idx, '') for idx in predicted_indices]
53
+
54
+ # Join the characters to form the solution string, excluding padding
55
+ solution = "".join([char for char in predicted_chars if char != '<pad>'])
56
+
57
+ return solution
58
+
59
+ # --- 2. Load the pre-trained Keras model ---
60
+ # This function will run once when the Gradio app starts.
61
+ def load_model():
62
+ try:
63
+ model = tf.keras.models.load_model(MODEL_PATH)
64
+ print(f"Model loaded successfully from {MODEL_PATH}")
65
+ return model
66
+ except Exception as e:
67
+ print(f"Error loading the model from {MODEL_PATH}: {e}")
68
+ # For deployment, this should ideally not fail.
69
+ # Ensure your model is correctly pushed as SavedModel.
70
+ return None
71
+
72
+ model = load_model()
73
+
74
+ # --- 3. Define the prediction function for Gradio ---
75
+ def predict_captcha(image: Image.Image) -> str:
76
+ if model is None:
77
+ return "Error: Model not loaded. Please check logs."
78
+
79
+ # Preprocess the input image to match model's expected input
80
+ # Ensure this matches the preprocessing done during training!
81
+ img = image.resize((200, 50)) # Model input width, height (from previous discussion)
82
+ img_array = np.array(img).astype(np.float32)
83
+ img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
84
+
85
+ # Uncomment and adjust if you applied normalization during training
86
+ # img_array = img_array / 255.0
87
+
88
+ # Make prediction
89
+ prediction = model.predict(img_array, verbose=0)
90
+
91
+ # Decode the prediction
92
+ decoded_solution = decode_prediction(prediction, int_to_char)
93
+
94
+ return decoded_solution
95
+
96
+ # --- 4. Create the Gradio Interface ---
97
+ iface = gr.Interface(
98
+ fn=predict_captcha,
99
+ inputs=gr.Image(type="pil", label="Upload Captcha Image"),
100
+ outputs=gr.Textbox(label="Predicted Captcha"),
101
+ title="Captcha Recognition",
102
+ description="Upload a captcha image (200x50 pixels expected) to get the predicted text.",
103
+ examples=[
104
+ # You can add example image paths here for the Gradio demo.
105
+ # These images should be present in your Hugging Face Space repository.
106
+ # e.g., "./example_captcha_1.png", "./example_captcha_2.png"
107
+ ],
108
+ allow_flagging="never", # Optional: Disable flagging data
109
+ live=False # Set to True for real-time inference as you draw/upload
110
+ )
111
+
112
+ # Launch the Gradio app
113
+ if __name__ == "__main__":
114
+ iface.launch()
captcha_recognition_model_char.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:542c386b8daffa1fef2749c2784f1c75afebfa2bd880ecf5d84b6b6717ac5322
3
+ size 298591478
int_to_char.json ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "0": "<pad>",
3
+ "1": "0",
4
+ "2": "1",
5
+ "3": "2",
6
+ "4": "3",
7
+ "5": "4",
8
+ "6": "5",
9
+ "7": "6",
10
+ "8": "7",
11
+ "9": "8",
12
+ "10": "9",
13
+ "11": "A",
14
+ "12": "B",
15
+ "13": "C",
16
+ "14": "D",
17
+ "15": "E",
18
+ "16": "F",
19
+ "17": "G",
20
+ "18": "H",
21
+ "19": "I",
22
+ "20": "J",
23
+ "21": "K",
24
+ "22": "L",
25
+ "23": "M",
26
+ "24": "N",
27
+ "25": "O",
28
+ "26": "P",
29
+ "27": "Q",
30
+ "28": "R",
31
+ "29": "S",
32
+ "30": "T",
33
+ "31": "U",
34
+ "32": "V",
35
+ "33": "W",
36
+ "34": "X",
37
+ "35": "Y",
38
+ "36": "Z",
39
+ "37": "a",
40
+ "38": "b",
41
+ "39": "c",
42
+ "40": "d",
43
+ "41": "e",
44
+ "42": "f",
45
+ "43": "g",
46
+ "44": "h",
47
+ "45": "i",
48
+ "46": "j",
49
+ "47": "k",
50
+ "48": "l",
51
+ "49": "m",
52
+ "50": "n",
53
+ "51": "o",
54
+ "52": "p",
55
+ "53": "q",
56
+ "54": "r",
57
+ "55": "s",
58
+ "56": "t",
59
+ "57": "u",
60
+ "58": "v",
61
+ "59": "w",
62
+ "60": "x",
63
+ "61": "y",
64
+ "62": "z"
65
+ }
requirements.txt ADDED
File without changes