Spaces:
Configuration error
Configuration error
| # app.py ← đặt ở root project | |
| import gradio as gr | |
| import json, shutil, tempfile | |
| from pathlib import Path | |
| from PIL import Image | |
| import cv2, numpy as np | |
| from src.inference import run_pipelineas | |
| # Auto-download weights nếu chưa có | |
| import os | |
| if not os.path.exists("best.pt"): | |
| from huggingface_hub import hf_hub_download | |
| hf_hub_download( | |
| repo_id="phamha/drawing-model-weights", | |
| filename="best.pt", | |
| local_dir="." | |
| ) | |
| CHECKPOINT = "best.pt" | |
| # ── Hàm xử lý cho Gradio ───────────────────────────────── | |
| def process(image: Image.Image): | |
| if image is None: | |
| return None, "{}", "Chưa có ảnh." | |
| # Lưu ảnh PIL tạm | |
| tmp_dir = tempfile.mkdtemp() | |
| tmp_path = f"{tmp_dir}/input.jpg" | |
| image.save(tmp_path, quality=95) | |
| try: | |
| result, vis_path = run_pipeline( | |
| image_path=tmp_path, | |
| output_dir=tmp_dir, | |
| checkpoint=CHECKPOINT, | |
| conf=0.3, | |
| ) | |
| except Exception as e: | |
| return None, "{}", f"Lỗi: {e}" | |
| # ── Ảnh visualize ───────────────────────────────────── | |
| vis_bgr = cv2.imread(vis_path) | |
| vis_rgb = cv2.cvtColor(vis_bgr, cv2.COLOR_BGR2RGB) | |
| # ── JSON (bỏ crop_path để gọn) ─────────────────────── | |
| clean = {"image": result["image"], "objects": []} | |
| for obj in result["objects"]: | |
| clean["objects"].append({ | |
| "id": obj["id"], | |
| "class": obj["class"], | |
| "confidence": obj["confidence"], | |
| "bbox": obj["bbox"], | |
| "ocr_content": obj["ocr_content"], | |
| }) | |
| json_str = json.dumps(clean, ensure_ascii=False, indent=2) | |
| # ── OCR text đẹp ────────────────────────────────────── | |
| ocr_parts = [] | |
| for obj in result["objects"]: | |
| if not obj["ocr_content"]: | |
| continue | |
| content = obj["ocr_content"] | |
| if isinstance(content, dict): # Table | |
| content = content.get("text", "") | |
| sep = "─" * 44 | |
| ocr_parts.append( | |
| f"{sep}\n" | |
| f"[{obj['class']} #{obj['id']}] " | |
| f"conf={obj['confidence']}\n" | |
| f"{sep}\n{content}" | |
| ) | |
| ocr_text = "\n\n".join(ocr_parts) if ocr_parts else "Không có vùng Note/Table." | |
| return vis_rgb, json_str, ocr_text | |
| # ── Giao diện Gradio ────────────────────────────────────── | |
| with gr.Blocks(title="Engineering Drawing Analyzer") as demo: | |
| gr.Markdown(""" | |
| # 🔧 Engineering Drawing Analyzer | |
| Tự động phát hiện và trích xuất **PartDrawing · Note · Table** từ bản vẽ kỹ thuật. | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| inp_image = gr.Image( | |
| type="pil", | |
| label="Upload bản vẽ kỹ thuật", | |
| ) | |
| btn = gr.Button("🔍 Detect & OCR", variant="primary") | |
| with gr.Column(scale=1): | |
| out_image = gr.Image(label="Kết quả detection") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| out_json = gr.Code( | |
| language="json", | |
| label="JSON output", | |
| lines=20, | |
| ) | |
| with gr.Column(scale=1): | |
| out_ocr = gr.Textbox( | |
| label="OCR content (Note & Table)", | |
| lines=20, | |
| max_lines=40, | |
| ) | |
| btn.click( | |
| fn=process, | |
| inputs=[inp_image], | |
| outputs=[out_image, out_json, out_ocr], | |
| ) | |
| gr.Examples( | |
| examples=[["test.jpg"]], # thêm ảnh mẫu nếu có | |
| inputs=[inp_image], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch( | |
| share=True, # tạo link public tạm thời | |
| server_port=7860, | |
| ) |