Commit ·
3bee947
1
Parent(s): 1476ac5
Tune web-safe border colors and selection outlines
Browse files
app.py
CHANGED
|
@@ -40,6 +40,8 @@ import numpy as np
|
|
| 40 |
|
| 41 |
|
| 42 |
PATCH_CHOICES = [14, 16, 28]
|
|
|
|
|
|
|
| 43 |
|
| 44 |
DEMO_VIDEO_PATH = os.path.join(
|
| 45 |
os.path.dirname(os.path.abspath(__file__)),
|
|
@@ -407,14 +409,25 @@ def overlay_selection(
|
|
| 407 |
keep = pix_mask.astype(bool)[..., None]
|
| 408 |
out = np.where(keep, frame_bgr, bg)
|
| 409 |
if outline:
|
|
|
|
|
|
|
|
|
|
| 410 |
for i in range(hb):
|
| 411 |
for j in range(wb):
|
| 412 |
if mask_grid[i, j]:
|
| 413 |
y0, x0 = i * patch, j * patch
|
|
|
|
| 414 |
cv2.rectangle(
|
| 415 |
-
out, (x0, y0), (
|
| 416 |
-
|
|
|
|
| 417 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 418 |
return out
|
| 419 |
|
| 420 |
|
|
@@ -996,8 +1009,14 @@ CUSTOM_CSS = """
|
|
| 996 |
:root, .gradio-container, .gradio-container.dark {
|
| 997 |
--ovc-grad: linear-gradient(135deg, #4f46e5 0%, #2563eb 50%, #06b6d4 100%);
|
| 998 |
--ovc-grad-soft: linear-gradient(135deg, rgba(79,70,229,0.10), rgba(6,182,212,0.10));
|
| 999 |
-
--ovc-ring: rgba(
|
| 1000 |
-
--ovc-ring-strong: rgba(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1001 |
}
|
| 1002 |
.gradio-container { max-width: 1320px !important; margin: 0 auto !important; }
|
| 1003 |
@keyframes ovc-shift {
|
|
@@ -1024,7 +1043,7 @@ CUSTOM_CSS = """
|
|
| 1024 |
linear-gradient(180deg, rgba(79,70,229,0.06), rgba(6,182,212,0.03)),
|
| 1025 |
repeating-linear-gradient(0deg, rgba(99,102,241,0.05) 0 1px, transparent 1px 28px),
|
| 1026 |
repeating-linear-gradient(90deg, rgba(99,102,241,0.05) 0 1px, transparent 1px 28px);
|
| 1027 |
-
border: 1px solid
|
| 1028 |
margin-bottom: 18px;
|
| 1029 |
position: relative;
|
| 1030 |
overflow: hidden;
|
|
@@ -1068,7 +1087,7 @@ CUSTOM_CSS = """
|
|
| 1068 |
padding: 7px 14px;
|
| 1069 |
border-radius: 999px;
|
| 1070 |
background: var(--background-fill-primary, #fff);
|
| 1071 |
-
border: 1px solid
|
| 1072 |
color: #4338ca;
|
| 1073 |
transition: transform 0.12s ease, box-shadow 0.18s ease,
|
| 1074 |
background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
|
|
@@ -1085,21 +1104,21 @@ CUSTOM_CSS = """
|
|
| 1085 |
.gradio-container.dark .ovc-links a {
|
| 1086 |
background: rgba(30,41,59,0.7);
|
| 1087 |
color: #c7d2fe;
|
| 1088 |
-
border-color:
|
| 1089 |
}
|
| 1090 |
|
| 1091 |
/* Cards */
|
| 1092 |
.ovc-card {
|
| 1093 |
border-radius: 16px !important;
|
| 1094 |
padding: 16px 18px !important;
|
| 1095 |
-
border: 1px solid
|
| 1096 |
background: var(--background-fill-primary) !important;
|
| 1097 |
box-shadow: 0 1px 3px rgba(15,23,42,0.04);
|
| 1098 |
transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
|
| 1099 |
animation: ovc-fade-in 0.32s ease-out;
|
| 1100 |
}
|
| 1101 |
.ovc-card:hover {
|
| 1102 |
-
border-color:
|
| 1103 |
box-shadow: 0 6px 22px rgba(15,23,42,0.07);
|
| 1104 |
}
|
| 1105 |
/* Primary outputs: subtle accent ring + lift */
|
|
@@ -1161,7 +1180,7 @@ CUSTOM_CSS = """
|
|
| 1161 |
.ovc-preset button {
|
| 1162 |
background: var(--ovc-grad-soft) !important;
|
| 1163 |
color: #4338ca !important;
|
| 1164 |
-
border: 1px solid
|
| 1165 |
border-radius: 10px !important;
|
| 1166 |
font-weight: 600 !important;
|
| 1167 |
transition: all 0.15s ease;
|
|
@@ -1179,7 +1198,7 @@ CUSTOM_CSS = """
|
|
| 1179 |
font-size: 0.80rem;
|
| 1180 |
padding: 22px 8px 10px;
|
| 1181 |
margin-top: 14px;
|
| 1182 |
-
border-top: 1px solid rgba(
|
| 1183 |
}
|
| 1184 |
#ovc-footer code {
|
| 1185 |
background: rgba(79,70,229,0.08);
|
|
@@ -1223,11 +1242,11 @@ CUSTOM_CSS = """
|
|
| 1223 |
.ovc-card-primary .video-container,
|
| 1224 |
.ovc-card-primary .image-container,
|
| 1225 |
.ovc-card-primary .plot-container {
|
| 1226 |
-
background: linear-gradient(180deg, rgba(99,102,241,0.05), rgba(6,182,212,0.
|
| 1227 |
-
border: 1px dashed rgba(
|
| 1228 |
}
|
| 1229 |
.ovc-card .gradio-video, .ovc-card .gradio-image, .ovc-card .gradio-plot {
|
| 1230 |
-
border-color:
|
| 1231 |
background: transparent !important;
|
| 1232 |
}
|
| 1233 |
/* Empty placeholder text inside Gradio components */
|
|
@@ -1245,7 +1264,7 @@ CUSTOM_CSS = """
|
|
| 1245 |
padding: 12px 14px;
|
| 1246 |
border-radius: 14px;
|
| 1247 |
background: linear-gradient(135deg, rgba(79,70,229,0.07), rgba(6,182,212,0.04));
|
| 1248 |
-
border: 1px solid
|
| 1249 |
transition: transform 0.18s ease, box-shadow 0.18s ease;
|
| 1250 |
}
|
| 1251 |
.ovc-stat:hover {
|
|
|
|
| 40 |
|
| 41 |
|
| 42 |
PATCH_CHOICES = [14, 16, 28]
|
| 43 |
+
PATCH_OUTLINE_OUTER_BGR = (42, 23, 15) # dark slate
|
| 44 |
+
PATCH_OUTLINE_INNER_BGR = (11, 158, 245) # amber
|
| 45 |
|
| 46 |
DEMO_VIDEO_PATH = os.path.join(
|
| 47 |
os.path.dirname(os.path.abspath(__file__)),
|
|
|
|
| 409 |
keep = pix_mask.astype(bool)[..., None]
|
| 410 |
out = np.where(keep, frame_bgr, bg)
|
| 411 |
if outline:
|
| 412 |
+
# A two-tone stroke survives browser H.264/yuv420p encoding better
|
| 413 |
+
# than a single 1 px saturated line.
|
| 414 |
+
outer_thickness = 2 if patch >= 20 else 1
|
| 415 |
for i in range(hb):
|
| 416 |
for j in range(wb):
|
| 417 |
if mask_grid[i, j]:
|
| 418 |
y0, x0 = i * patch, j * patch
|
| 419 |
+
y1, x1 = y0 + patch - 1, x0 + patch - 1
|
| 420 |
cv2.rectangle(
|
| 421 |
+
out, (x0, y0), (x1, y1),
|
| 422 |
+
PATCH_OUTLINE_OUTER_BGR, outer_thickness,
|
| 423 |
+
lineType=cv2.LINE_AA,
|
| 424 |
)
|
| 425 |
+
if patch >= 6 and (x1 - x0) >= 3 and (y1 - y0) >= 3:
|
| 426 |
+
cv2.rectangle(
|
| 427 |
+
out, (x0 + 1, y0 + 1), (x1 - 1, y1 - 1),
|
| 428 |
+
PATCH_OUTLINE_INNER_BGR, 1,
|
| 429 |
+
lineType=cv2.LINE_AA,
|
| 430 |
+
)
|
| 431 |
return out
|
| 432 |
|
| 433 |
|
|
|
|
| 1009 |
:root, .gradio-container, .gradio-container.dark {
|
| 1010 |
--ovc-grad: linear-gradient(135deg, #4f46e5 0%, #2563eb 50%, #06b6d4 100%);
|
| 1011 |
--ovc-grad-soft: linear-gradient(135deg, rgba(79,70,229,0.10), rgba(6,182,212,0.10));
|
| 1012 |
+
--ovc-ring: rgba(79,70,229,0.40);
|
| 1013 |
+
--ovc-ring-strong: rgba(79,70,229,0.62);
|
| 1014 |
+
--ovc-line: rgba(100,116,139,0.34);
|
| 1015 |
+
--ovc-line-strong: rgba(100,116,139,0.48);
|
| 1016 |
+
--ovc-line-accent-soft: rgba(79,70,229,0.28);
|
| 1017 |
+
--ovc-line-accent: rgba(79,70,229,0.40);
|
| 1018 |
+
--ovc-line-accent-strong: rgba(79,70,229,0.58);
|
| 1019 |
+
--ovc-line-cyan: rgba(6,182,212,0.26);
|
| 1020 |
}
|
| 1021 |
.gradio-container { max-width: 1320px !important; margin: 0 auto !important; }
|
| 1022 |
@keyframes ovc-shift {
|
|
|
|
| 1043 |
linear-gradient(180deg, rgba(79,70,229,0.06), rgba(6,182,212,0.03)),
|
| 1044 |
repeating-linear-gradient(0deg, rgba(99,102,241,0.05) 0 1px, transparent 1px 28px),
|
| 1045 |
repeating-linear-gradient(90deg, rgba(99,102,241,0.05) 0 1px, transparent 1px 28px);
|
| 1046 |
+
border: 1px solid var(--ovc-line-accent-soft);
|
| 1047 |
margin-bottom: 18px;
|
| 1048 |
position: relative;
|
| 1049 |
overflow: hidden;
|
|
|
|
| 1087 |
padding: 7px 14px;
|
| 1088 |
border-radius: 999px;
|
| 1089 |
background: var(--background-fill-primary, #fff);
|
| 1090 |
+
border: 1px solid var(--ovc-line-accent);
|
| 1091 |
color: #4338ca;
|
| 1092 |
transition: transform 0.12s ease, box-shadow 0.18s ease,
|
| 1093 |
background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
|
|
|
|
| 1104 |
.gradio-container.dark .ovc-links a {
|
| 1105 |
background: rgba(30,41,59,0.7);
|
| 1106 |
color: #c7d2fe;
|
| 1107 |
+
border-color: var(--ovc-line-accent-strong);
|
| 1108 |
}
|
| 1109 |
|
| 1110 |
/* Cards */
|
| 1111 |
.ovc-card {
|
| 1112 |
border-radius: 16px !important;
|
| 1113 |
padding: 16px 18px !important;
|
| 1114 |
+
border: 1px solid var(--ovc-line) !important;
|
| 1115 |
background: var(--background-fill-primary) !important;
|
| 1116 |
box-shadow: 0 1px 3px rgba(15,23,42,0.04);
|
| 1117 |
transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
|
| 1118 |
animation: ovc-fade-in 0.32s ease-out;
|
| 1119 |
}
|
| 1120 |
.ovc-card:hover {
|
| 1121 |
+
border-color: var(--ovc-line-accent) !important;
|
| 1122 |
box-shadow: 0 6px 22px rgba(15,23,42,0.07);
|
| 1123 |
}
|
| 1124 |
/* Primary outputs: subtle accent ring + lift */
|
|
|
|
| 1180 |
.ovc-preset button {
|
| 1181 |
background: var(--ovc-grad-soft) !important;
|
| 1182 |
color: #4338ca !important;
|
| 1183 |
+
border: 1px solid var(--ovc-line-accent-soft) !important;
|
| 1184 |
border-radius: 10px !important;
|
| 1185 |
font-weight: 600 !important;
|
| 1186 |
transition: all 0.15s ease;
|
|
|
|
| 1198 |
font-size: 0.80rem;
|
| 1199 |
padding: 22px 8px 10px;
|
| 1200 |
margin-top: 14px;
|
| 1201 |
+
border-top: 1px solid rgba(100,116,139,0.22);
|
| 1202 |
}
|
| 1203 |
#ovc-footer code {
|
| 1204 |
background: rgba(79,70,229,0.08);
|
|
|
|
| 1242 |
.ovc-card-primary .video-container,
|
| 1243 |
.ovc-card-primary .image-container,
|
| 1244 |
.ovc-card-primary .plot-container {
|
| 1245 |
+
background: linear-gradient(180deg, rgba(99,102,241,0.05), rgba(6,182,212,0.025)) !important;
|
| 1246 |
+
border: 1px dashed rgba(79,70,229,0.38) !important;
|
| 1247 |
}
|
| 1248 |
.ovc-card .gradio-video, .ovc-card .gradio-image, .ovc-card .gradio-plot {
|
| 1249 |
+
border-color: var(--ovc-line) !important;
|
| 1250 |
background: transparent !important;
|
| 1251 |
}
|
| 1252 |
/* Empty placeholder text inside Gradio components */
|
|
|
|
| 1264 |
padding: 12px 14px;
|
| 1265 |
border-radius: 14px;
|
| 1266 |
background: linear-gradient(135deg, rgba(79,70,229,0.07), rgba(6,182,212,0.04));
|
| 1267 |
+
border: 1px solid var(--ovc-line-accent-soft);
|
| 1268 |
transition: transform 0.18s ease, box-shadow 0.18s ease;
|
| 1269 |
}
|
| 1270 |
.ovc-stat:hover {
|