RefDiffNet / app.py
ShashwatGupta23's picture
RefDiffNet: standalone A11_CA prebackbone Gradio Space
5673379
Raw History Blame
5.13 kB
"""Gradio demo: PCB defect + golden reference -> enriched image (A11_CA prebackbone)."""
from __future__ import annotations
import os
import socket
from pathlib import Path
_ROOT = Path(__file__).resolve().parent
def _is_hf_space() -> bool:
return bool(os.environ.get("SPACE_ID") or os.environ.get("SYSTEM") == "spaces")
def _configure_runtime() -> None:
os.environ.setdefault("GRADIO_SERVER_PORT", os.environ.get("PORT", "7860"))
os.environ.setdefault(
"PREBACKBONE_ONLY_WEIGHTS",
str(_ROOT / "weights" / "prebackbone_a11_ca.pt"),
)
if _is_hf_space():
os.environ.setdefault("PRELOAD_MODEL", "1")
os.environ.setdefault("GRADIO_SERVER_NAME", "0.0.0.0")
_configure_runtime()
import gradio_patch
gradio_patch.apply()
import gradio as gr
import numpy as np
from PIL import Image
from prebackbone_infer import enrich_pair, get_enricher
TITLE = "RefDiffNet — PCB Reference–Defect Enrichment"
DESCRIPTION = """
Upload a **defect PCB image** and its **golden reference** (same H×W, pre-aligned — e.g. `*_input.jpg` / `*_reference.jpg` from training).
The A11_CA prebackbone outputs an **enriched** image: `enriched = defect + α · gate · delta`
"""
def run_demo(defect_path: str | None, reference_path: str | None):
if not defect_path or not reference_path:
raise gr.Error("Please upload both defect and reference images.")
defect_rgb, ref_rgb, enriched_rgb = enrich_pair(defect_path, reference_path)
defect_rgb = np.array(defect_rgb, dtype=np.uint8, copy=True)
ref_rgb = np.array(ref_rgb, dtype=np.uint8, copy=True)
enriched_rgb = np.array(enriched_rgb, dtype=np.uint8, copy=True)
h = max(defect_rgb.shape[0], ref_rgb.shape[0], enriched_rgb.shape[0])
def _pad(im: np.ndarray) -> np.ndarray:
if im.shape[0] == h:
return im
pad = h - im.shape[0]
return np.pad(im, ((0, pad), (0, 0), (0, 0)), mode="constant", constant_values=114)
row = np.concatenate([_pad(defect_rgb), _pad(ref_rgb), _pad(enriched_rgb)], axis=1)
return Image.fromarray(enriched_rgb), Image.fromarray(row)
def _example_pairs() -> list[list[str]]:
pairs: list[list[str]] = []
ex_dir = _ROOT / "examples"
if not ex_dir.is_dir():
return pairs
for inp in sorted(ex_dir.glob("*_input.jpg")):
ref = inp.with_name(inp.name.replace("_input.", "_reference."))
if ref.is_file():
pairs.append([str(inp), str(ref)])
return pairs
def _preload_model() -> None:
try:
get_enricher()
print("[RefDiffNet] Prebackbone loaded.")
except FileNotFoundError as e:
print(f"[RefDiffNet] WARN: {e}")
def build_demo() -> gr.Blocks:
with gr.Blocks(title=TITLE) as demo:
gr.Markdown(DESCRIPTION.strip())
with gr.Row():
defect_in = gr.Image(type="filepath", label="Defect image (input)")
ref_in = gr.Image(type="filepath", label="Golden reference")
run_btn = gr.Button("Run enrichment", variant="primary")
with gr.Row():
out_enriched = gr.Image(type="pil", label="Enriched output")
out_row = gr.Image(type="pil", label="Defect | Reference | Enriched")
run_btn.click(run_demo, inputs=[defect_in, ref_in], outputs=[out_enriched, out_row])
examples = _example_pairs()
if examples:
gr.Examples(
examples=examples,
inputs=[defect_in, ref_in],
examples_per_page=3,
label="Example pairs (pre-aligned HR-IPCB samples)",
)
return demo
demo = build_demo()
def _launch_kwargs() -> dict:
if _is_hf_space():
return {
"server_name": "0.0.0.0",
"server_port": int(os.environ.get("PORT", "7860")),
"share": False,
}
server_name = os.environ.get("GRADIO_SERVER_NAME", "127.0.0.1")
preferred_port = int(os.environ.get("PORT", os.environ.get("GRADIO_SERVER_PORT", "7860")))
bind_host = "127.0.0.1" if server_name in ("127.0.0.1", "localhost") else server_name
server_port = preferred_port
if server_name in ("127.0.0.1", "localhost"):
for port in range(preferred_port, preferred_port + 20):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sock.bind((bind_host, port))
server_port = port
break
except OSError:
continue
share = os.environ.get("GRADIO_SHARE", "").lower() in ("1", "true", "yes")
return {
"server_name": server_name,
"server_port": server_port,
"share": share,
}
if __name__ == "__main__":
print(f"[RefDiffNet] gradio {getattr(gr, '__version__', 'unknown')}")
if os.environ.get("PRELOAD_MODEL", "0").lower() in ("1", "true", "yes"):
_preload_model()
demo.launch(
**(_launch_kwargs()),
show_error=True,
inbrowser=False,
prevent_thread_lock=False,
)