Spaces:
Sleeping
Sleeping
mohakkapoor4
commited on
Commit
·
de40c22
1
Parent(s):
9476a7e
Add character accuracy calculation and update UI to display accuracy alongside predictions. Modify solve function to accept ground truth input and return accuracy results.
Browse files
app.py
CHANGED
|
@@ -20,6 +20,24 @@ def random_text():
|
|
| 20 |
L = random.randint(cfg.CAPTCHA_LEN_LOWER_LIMIT, cfg.CAPTCHA_LEN_UPPER_LIMIT)
|
| 21 |
return "".join(random.choices(cfg.chars, k=L))
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
def ui_generate():
|
| 24 |
text = random_text()
|
| 25 |
filename = f"{text}_{random.randint(1000,9999)}.png"
|
|
@@ -34,27 +52,37 @@ def ui_generate():
|
|
| 34 |
solve_btn_state = gr.update(interactive=True, variant="primary")
|
| 35 |
return img, text, filepath, solve_btn_state
|
| 36 |
|
| 37 |
-
def ui_solve(path_hint: str):
|
| 38 |
if path_hint and os.path.exists(path_hint):
|
| 39 |
tensor = inf.preprocess_image(path_hint, (cfg.W_max, cfg.H))
|
| 40 |
pred = inf.predict_captcha(MODEL, tensor, DEVICE)
|
| 41 |
-
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
with gr.Blocks(title="CAPTCHA OCR (checkpoint)") as demo:
|
| 45 |
gr.Markdown("## CAPTCHA OCR demo")
|
| 46 |
|
| 47 |
with gr.Row():
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
gt_out = gr.Textbox(label="Ground Truth", interactive=False)
|
| 50 |
|
| 51 |
with gr.Row():
|
| 52 |
img_out = gr.Image(label="Generated CAPTCHA", type="pil")
|
| 53 |
path_box = gr.Textbox(label="Internal Path", interactive=False, visible=False)
|
| 54 |
|
| 55 |
-
#
|
| 56 |
-
|
| 57 |
-
|
|
|
|
| 58 |
|
| 59 |
# Generate: outputs image, ground truth, path, and enables Solve (green)
|
| 60 |
gen_btn.click(
|
|
@@ -65,8 +93,8 @@ with gr.Blocks(title="CAPTCHA OCR (checkpoint)") as demo:
|
|
| 65 |
# Solve: only uses the internal path (no upload option anymore)
|
| 66 |
solve_btn.click(
|
| 67 |
fn=ui_solve,
|
| 68 |
-
inputs=[path_box],
|
| 69 |
-
outputs=[pred_out],
|
| 70 |
)
|
| 71 |
|
| 72 |
if __name__ == "__main__":
|
|
|
|
| 20 |
L = random.randint(cfg.CAPTCHA_LEN_LOWER_LIMIT, cfg.CAPTCHA_LEN_UPPER_LIMIT)
|
| 21 |
return "".join(random.choices(cfg.chars, k=L))
|
| 22 |
|
| 23 |
+
def calculate_accuracy(prediction, target):
|
| 24 |
+
"""Calculate character-by-character accuracy."""
|
| 25 |
+
if not prediction or not target:
|
| 26 |
+
return "0%"
|
| 27 |
+
|
| 28 |
+
correct_chars = 0
|
| 29 |
+
min_len = min(len(prediction), len(target))
|
| 30 |
+
|
| 31 |
+
for i in range(min_len):
|
| 32 |
+
if prediction[i] == target[i]:
|
| 33 |
+
correct_chars += 1
|
| 34 |
+
|
| 35 |
+
if min_len == 0:
|
| 36 |
+
return "0%"
|
| 37 |
+
|
| 38 |
+
accuracy = (correct_chars / min_len) * 100
|
| 39 |
+
return f"{accuracy:.1f}%"
|
| 40 |
+
|
| 41 |
def ui_generate():
|
| 42 |
text = random_text()
|
| 43 |
filename = f"{text}_{random.randint(1000,9999)}.png"
|
|
|
|
| 52 |
solve_btn_state = gr.update(interactive=True, variant="primary")
|
| 53 |
return img, text, filepath, solve_btn_state
|
| 54 |
|
| 55 |
+
def ui_solve(path_hint: str, ground_truth: str):
|
| 56 |
if path_hint and os.path.exists(path_hint):
|
| 57 |
tensor = inf.preprocess_image(path_hint, (cfg.W_max, cfg.H))
|
| 58 |
pred = inf.predict_captcha(MODEL, tensor, DEVICE)
|
| 59 |
+
|
| 60 |
+
# Calculate accuracy
|
| 61 |
+
accuracy = calculate_accuracy(pred, ground_truth)
|
| 62 |
+
|
| 63 |
+
return accuracy, pred
|
| 64 |
+
return "0%", "No image generated yet. Click Generate CAPTCHA first."
|
| 65 |
|
| 66 |
with gr.Blocks(title="CAPTCHA OCR (checkpoint)") as demo:
|
| 67 |
gr.Markdown("## CAPTCHA OCR demo")
|
| 68 |
|
| 69 |
with gr.Row():
|
| 70 |
+
# Left column: Generate button + Solve button stacked vertically
|
| 71 |
+
with gr.Column(scale=1):
|
| 72 |
+
gen_btn = gr.Button("Generate CAPTCHA", variant="primary")
|
| 73 |
+
solve_btn = gr.Button("Solve", interactive=False, variant="secondary")
|
| 74 |
+
|
| 75 |
+
# Right column: Ground Truth
|
| 76 |
gt_out = gr.Textbox(label="Ground Truth", interactive=False)
|
| 77 |
|
| 78 |
with gr.Row():
|
| 79 |
img_out = gr.Image(label="Generated CAPTCHA", type="pil")
|
| 80 |
path_box = gr.Textbox(label="Internal Path", interactive=False, visible=False)
|
| 81 |
|
| 82 |
+
# Prediction row split into two columns
|
| 83 |
+
with gr.Row():
|
| 84 |
+
accuracy_out = gr.Textbox(label="Character Accuracy", interactive=False)
|
| 85 |
+
pred_out = gr.Textbox(label="Prediction", interactive=False)
|
| 86 |
|
| 87 |
# Generate: outputs image, ground truth, path, and enables Solve (green)
|
| 88 |
gen_btn.click(
|
|
|
|
| 93 |
# Solve: only uses the internal path (no upload option anymore)
|
| 94 |
solve_btn.click(
|
| 95 |
fn=ui_solve,
|
| 96 |
+
inputs=[path_box, gt_out],
|
| 97 |
+
outputs=[accuracy_out, pred_out],
|
| 98 |
)
|
| 99 |
|
| 100 |
if __name__ == "__main__":
|