Bobby Claude Fable 5 commited on
Commit
7994bcc
·
1 Parent(s): 723861e

Force https root_url (custom-domain proxy drops x-forwarded-proto); harden count_crowd with cuda fallback + error handling; 60s GPU reservation

Browse files
Files changed (1) hide show
  1. app.py +40 -9
app.py CHANGED
@@ -5,12 +5,30 @@ os.environ.setdefault("PYTORCH_ENABLE_MPS_FALLBACK", "1")
5
 
6
  import cv2
7
  import gradio as gr
 
8
  import spaces
9
  import torch
10
  from PIL import Image
11
 
12
  import count
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  TILE = 768
15
  OVERLAP = 192
16
  UPSCALE = 1.0
@@ -33,7 +51,7 @@ def add_watermark(image):
33
  return image.convert("RGB")
34
 
35
 
36
- @spaces.GPU(duration=5)
37
  def count_crowd(image_path, threshold):
38
  if image_path is None:
39
  return None, "Upload an image first."
@@ -41,12 +59,25 @@ def count_crowd(image_path, threshold):
41
  if image_bgr is None:
42
  return None, "Could not read that image."
43
 
44
- device = torch.device("cuda")
45
- model = _model.to(device)
46
- points = count.predict_points_tiled(model, image_bgr, device, UPSCALE, TILE, OVERLAP, float(threshold))
47
- total = int(points.shape[0])
48
- overlay = add_watermark(count.render_overlay(image_bgr, points, total))
49
- return overlay, f"{total:,} people"
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
 
52
  css = """
@@ -67,7 +98,7 @@ footer {
67
  max-width: 1100px !important;
68
  }
69
  .gradio-container a { text-decoration: none !important; }
70
- #count-box .output-class, #count-box .label-content, #count-box .text { color: #5A11FF !important; font-weight: 800 !important; }
71
  #count-box { color: #5A11FF !important; }
72
  .sponsor-banner {
73
  text-align: center;
@@ -209,7 +240,7 @@ with gr.Blocks(title="Crowd Counter | SkyeBrowse") as demo:
209
  threshold = gr.Slider(0.2, 0.6, value=0.35, step=0.05, label="Head-confidence threshold (lower = more dense-core recall)")
210
  with gr.Column(scale=1, min_width=300):
211
  overlay_output = gr.Image(type="pil", label="Counted overlay", interactive=False)
212
- count_output = gr.Label(label="Estimated count", elem_id="count-box")
213
 
214
  inputs = [image_input, threshold]
215
  outputs = [overlay_output, count_output]
 
5
 
6
  import cv2
7
  import gradio as gr
8
+ import gradio.route_utils
9
  import spaces
10
  import torch
11
  from PIL import Image
12
 
13
  import count
14
 
15
+ # The crowd.skyebrowse.com proxy forwards x-forwarded-host but not
16
+ # x-forwarded-proto, so Gradio resolves an http:// root and every asset/API
17
+ # URL gets mixed-content blocked on the https page. Upgrade the scheme.
18
+ _original_get_root_url = gradio.route_utils.get_root_url
19
+
20
+
21
+ def _https_get_root_url(request, route_path, root_path):
22
+ root_url = _original_get_root_url(request, route_path, root_path)
23
+ if root_url.startswith("http://") and not any(
24
+ host in root_url for host in ("localhost", "127.0.0.1", "0.0.0.0")
25
+ ):
26
+ root_url = "https://" + root_url[len("http://"):]
27
+ return root_url
28
+
29
+
30
+ gradio.route_utils.get_root_url = _https_get_root_url
31
+
32
  TILE = 768
33
  OVERLAP = 192
34
  UPSCALE = 1.0
 
51
  return image.convert("RGB")
52
 
53
 
54
+ @spaces.GPU(duration=60)
55
  def count_crowd(image_path, threshold):
56
  if image_path is None:
57
  return None, "Upload an image first."
 
59
  if image_bgr is None:
60
  return None, "Could not read that image."
61
 
62
+ try:
63
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
64
+ model = _model.to(device)
65
+ with torch.inference_mode():
66
+ points = count.predict_points_tiled(
67
+ model,
68
+ image_bgr,
69
+ device,
70
+ UPSCALE,
71
+ TILE,
72
+ OVERLAP,
73
+ float(threshold),
74
+ )
75
+ total = int(points.shape[0])
76
+ overlay = add_watermark(count.render_overlay(image_bgr, points, total))
77
+ return overlay, f"{total:,} people"
78
+ except Exception as exc:
79
+ print(f"count_crowd failed: {exc}", flush=True)
80
+ return None, "Crowd counter failed. Please try a smaller image or try again in a minute."
81
 
82
 
83
  css = """
 
98
  max-width: 1100px !important;
99
  }
100
  .gradio-container a { text-decoration: none !important; }
101
+ #count-box .output-class, #count-box .label-content, #count-box .text, #count-box textarea, #count-box input { color: #5A11FF !important; font-weight: 800 !important; }
102
  #count-box { color: #5A11FF !important; }
103
  .sponsor-banner {
104
  text-align: center;
 
240
  threshold = gr.Slider(0.2, 0.6, value=0.35, step=0.05, label="Head-confidence threshold (lower = more dense-core recall)")
241
  with gr.Column(scale=1, min_width=300):
242
  overlay_output = gr.Image(type="pil", label="Counted overlay", interactive=False)
243
+ count_output = gr.Textbox(label="Estimated count", elem_id="count-box", interactive=False)
244
 
245
  inputs = [image_input, threshold]
246
  outputs = [overlay_output, count_output]