CoolFace
Apppublic

opencv/text_recognition_crnn

sourceHugging Faceupdated 1y agoView on Hugging Face
1likes
app.py142 linesDownload Raw Back to root
1import cv2 as cv2import numpy as np3import gradio as gr4from huggingface_hub import hf_hub_download5from ppocr_det import PPOCRDet6from crnn import CRNN7 8# Download model files from Hugging Face9det_model_path = hf_hub_download(10    repo_id="opencv/text_detection_ppocr",11    filename="text_detection_en_ppocrv3_2023may.onnx"12)13rec_model_path = hf_hub_download(14    repo_id="opencv/text_recognition_crnn",15    filename="text_recognition_CRNN_EN_2021sep.onnx"16)17 18# DNN backend and target19backend_id = cv.dnn.DNN_BACKEND_OPENCV20target_id = cv.dnn.DNN_TARGET_CPU21 22# Detector and recognizer setup23detector = PPOCRDet(24    modelPath=det_model_path,25    inputSize=[736, 736],26    binaryThreshold=0.3,27    polygonThreshold=0.5,28    maxCandidates=200,29    unclipRatio=2.0,30    backendId=backend_id,31    targetId=target_id32)33 34recognizer = CRNN(35    modelPath=rec_model_path,36    backendId=backend_id,37    targetId=target_id38)39 40def detect_and_recognize(input_image):41    bgr = cv.cvtColor(input_image, cv.COLOR_RGB2BGR)42    h_orig, w_orig = input_image.shape[:2]43    resized = cv.resize(bgr, (736, 736))44    scale_w = w_orig / 73645    scale_h = h_orig / 73646 47    # Detect & recognize48    det_results, _ = detector.infer(resized)49    texts = [recognizer.infer(resized, box.reshape(8)) for box in det_results]50 51    # Prepare canvases52    left = input_image.copy()53    right = np.ones_like(input_image) * 25554 55    for box_raw, text in zip(det_results, texts):56        # Rescale box to original image coords57        box = np.int32([[pt[0] * scale_w, pt[1] * scale_h] for pt in box_raw])58 59        # Compute box dimensions60        xs = box[:, 0]61        box_w = xs.max() - xs.min()62        # box height (average vertical edges)63        h1 = np.linalg.norm(box[1] - box[0])64        h2 = np.linalg.norm(box[2] - box[3])65        box_h = (h1 + h2) / 2.066 67        # Initial font scale so text height ≈ 80% of box height68        (_, th0), _ = cv.getTextSize(text, cv.FONT_HERSHEY_SIMPLEX, 1.0, 1)69        font_scale = (box_h * 0.8) / th0 if th0 > 0 else 1.070        font_thickness = max(1, int(font_scale))71 72        # Re-measure text size with this scale73        (tw, th), _ = cv.getTextSize(text, cv.FONT_HERSHEY_SIMPLEX, font_scale, font_thickness)74 75        # If text is wider than box or taller than box, scale down to fit76        scale_x = box_w / tw if tw > 0 else 1.077        scale_y = (box_h * 0.8) / th if th > 0 else 1.078        final_scale = font_scale * min(1.0, scale_x, scale_y)79        font_scale = final_scale80        font_thickness = max(1, int(np.floor(font_scale)))81 82        # Draw boxes on both panels83        cv.polylines(left, [box], isClosed=True, color=(0, 0, 255), thickness=2)84        cv.polylines(right, [box], isClosed=True, color=(0, 0, 255), thickness=2)85 86        # Draw text on whiteboard, just above top-left corner87        x0, y0 = box[0]88        y_text = max(0, int(y0 - 5))89        cv.putText(90            right, text, (int(x0), y_text),91            cv.FONT_HERSHEY_SIMPLEX,92            font_scale, (0, 0, 0), font_thickness93        )94 95    combined = cv.hconcat([left, right])96    return combined97 98with gr.Blocks(css='''.example * {99    font-style: italic;100    font-size: 18px !important;101    color: #0ea5e9 !important;102    }''') as demo:103 104    gr.Markdown("## Scene Text Detection and Recognition (PPOCR + CRNN)")105    gr.Markdown("Upload an image with scene text to detect text regions and recognize text using OpenCV DNN with PPOCR + CRNN models.")106 107    input_img = gr.Image(type="numpy", label="Upload Image")108    output_img = gr.Image(type="numpy", label="Detected Text Image")109 110    input_img.change(fn=lambda: (None), outputs=output_img)111 112    with gr.Row():113        submit_btn = gr.Button("Submit", variant="primary")114        clear_btn = gr.Button("Clear")115 116    submit_btn.click(117        fn=detect_and_recognize,118        inputs=input_img,119        outputs=output_img120    )121 122    clear_btn.click(123        fn=lambda: (None, None),124        inputs=[],125        outputs=[input_img, output_img]126    )127 128    gr.Markdown("Click on any example to try it.", elem_classes=["example"])129 130    gr.Examples(131        examples=[132            ["examples/text_det_test2.jpg"],133            ["examples/right.jpg"]134        ],135        inputs=input_img136    )137 138    gr.Markdown("**Note**: Left side of output shows detected regions, right side shows recognized text.")139 140if __name__ == "__main__":141    demo.launch()142