Spaces:
Sleeping
Sleeping
Rattatammanoon Parwasuk commited on
Commit ·
0c1c4ab
1
Parent(s): 75c201a
Update app theme colors and styles for improved UI consistency and aesthetics
Browse files
app.py
CHANGED
|
@@ -62,10 +62,11 @@ CUSTOM_CSS = """
|
|
| 62 |
}
|
| 63 |
|
| 64 |
:root {
|
| 65 |
-
|
| 66 |
-
--primary
|
| 67 |
-
--
|
| 68 |
-
--
|
|
|
|
| 69 |
--success: #22c55e;
|
| 70 |
--error: #ef4444;
|
| 71 |
--warning: #eab308;
|
|
@@ -73,7 +74,7 @@ CUSTOM_CSS = """
|
|
| 73 |
--bg-card: rgba(30, 41, 59, 0.9);
|
| 74 |
--bg-card-hover: rgba(51, 65, 85, 0.9);
|
| 75 |
--text-white: #ffffff;
|
| 76 |
-
--text-bright: #
|
| 77 |
--text-light: #e2e8f0;
|
| 78 |
--text-muted: #94a3b8;
|
| 79 |
--border: rgba(71, 85, 105, 0.8);
|
|
@@ -119,7 +120,7 @@ CUSTOM_CSS = """
|
|
| 119 |
font-family: 'Kanit', sans-serif;
|
| 120 |
font-size: 3.5rem;
|
| 121 |
font-weight: 700;
|
| 122 |
-
background: linear-gradient(135deg, #
|
| 123 |
-webkit-background-clip: text;
|
| 124 |
-webkit-text-fill-color: transparent;
|
| 125 |
background-clip: text;
|
|
@@ -128,7 +129,7 @@ CUSTOM_CSS = """
|
|
| 128 |
}
|
| 129 |
|
| 130 |
.main-title p {
|
| 131 |
-
color: #
|
| 132 |
font-size: 1.15rem;
|
| 133 |
font-weight: 500;
|
| 134 |
}
|
|
@@ -183,7 +184,7 @@ CUSTOM_CSS = """
|
|
| 183 |
|
| 184 |
/* Primary Button */
|
| 185 |
.primary-btn {
|
| 186 |
-
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%) !important;
|
| 187 |
border: 1px solid rgba(255, 255, 255, 0.2) !important;
|
| 188 |
border-radius: 12px !important;
|
| 189 |
padding: 14px 36px !important;
|
|
@@ -191,7 +192,7 @@ CUSTOM_CSS = """
|
|
| 191 |
font-size: 1.05rem !important;
|
| 192 |
color: white !important;
|
| 193 |
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
| 194 |
-
box-shadow: 0 4px 20px rgba(
|
| 195 |
text-transform: none !important;
|
| 196 |
backdrop-filter: blur(5px) !important;
|
| 197 |
-webkit-backdrop-filter: blur(5px) !important;
|
|
@@ -199,7 +200,7 @@ CUSTOM_CSS = """
|
|
| 199 |
|
| 200 |
.primary-btn:hover {
|
| 201 |
transform: translateY(-3px) !important;
|
| 202 |
-
box-shadow: 0 8px 30px rgba(
|
| 203 |
}
|
| 204 |
|
| 205 |
/* Extract Button - Different color */
|
|
@@ -226,7 +227,7 @@ CUSTOM_CSS = """
|
|
| 226 |
.edit-field input,
|
| 227 |
.edit-field textarea {
|
| 228 |
background: rgba(30, 41, 59, 0.95) !important;
|
| 229 |
-
border: 2px solid rgba(
|
| 230 |
color: #ffffff !important;
|
| 231 |
font-size: 1.1rem !important;
|
| 232 |
font-weight: 500 !important;
|
|
@@ -266,8 +267,8 @@ CUSTOM_CSS = """
|
|
| 266 |
margin: 1rem 0 !important;
|
| 267 |
border-radius: 12px !important;
|
| 268 |
overflow: hidden !important;
|
| 269 |
-
border: 2px solid rgba(
|
| 270 |
-
box-shadow: 0 4px 20px rgba(
|
| 271 |
background: rgba(30, 41, 59, 0.9) !important;
|
| 272 |
backdrop-filter: blur(10px) !important;
|
| 273 |
-webkit-backdrop-filter: blur(10px) !important;
|
|
@@ -282,7 +283,7 @@ CUSTOM_CSS = """
|
|
| 282 |
}
|
| 283 |
|
| 284 |
.cropped-plate label {
|
| 285 |
-
color: #
|
| 286 |
font-weight: 600 !important;
|
| 287 |
margin-bottom: 0.5rem !important;
|
| 288 |
}
|
|
@@ -301,8 +302,8 @@ CUSTOM_CSS = """
|
|
| 301 |
|
| 302 |
.image-upload:hover {
|
| 303 |
border-color: var(--primary) !important;
|
| 304 |
-
background: rgba(
|
| 305 |
-
box-shadow: 0 8px 30px rgba(
|
| 306 |
}
|
| 307 |
|
| 308 |
/* Textbox / Textarea styling */
|
|
@@ -320,7 +321,7 @@ textarea, input[type="text"] {
|
|
| 320 |
|
| 321 |
textarea:focus, input[type="text"]:focus {
|
| 322 |
border-color: var(--primary) !important;
|
| 323 |
-
box-shadow: 0 0 0 3px rgba(
|
| 324 |
outline: none !important;
|
| 325 |
}
|
| 326 |
|
|
@@ -379,7 +380,7 @@ table {
|
|
| 379 |
}
|
| 380 |
|
| 381 |
th {
|
| 382 |
-
background: linear-gradient(135deg, #
|
| 383 |
color: #ffffff !important;
|
| 384 |
font-weight: 700 !important;
|
| 385 |
padding: 14px 16px !important;
|
|
@@ -481,9 +482,9 @@ button[role="tab"]:hover {
|
|
| 481 |
}
|
| 482 |
|
| 483 |
button[role="tab"][aria-selected="true"] {
|
| 484 |
-
background: linear-gradient(135deg, #
|
| 485 |
color: #ffffff !important;
|
| 486 |
-
border-color: #
|
| 487 |
font-weight: 700 !important;
|
| 488 |
box-shadow: 0 4px 15px rgba(14, 165, 233, 0.4) !important;
|
| 489 |
}
|
|
@@ -528,7 +529,7 @@ button[role="tab"][aria-selected="true"] {
|
|
| 528 |
}
|
| 529 |
|
| 530 |
.footer a {
|
| 531 |
-
color: #
|
| 532 |
text-decoration: none;
|
| 533 |
font-weight: 600;
|
| 534 |
transition: color 0.2s ease;
|
|
@@ -596,7 +597,7 @@ hr {
|
|
| 596 |
}
|
| 597 |
|
| 598 |
.how-to-use strong {
|
| 599 |
-
color: #
|
| 600 |
font-weight: 600 !important;
|
| 601 |
}
|
| 602 |
|
|
@@ -1065,8 +1066,8 @@ def create_demo_interface() -> gr.Blocks:
|
|
| 1065 |
title="AI OCR - Thai License Plate Recognition",
|
| 1066 |
css=CUSTOM_CSS,
|
| 1067 |
theme=gr.themes.Base(
|
| 1068 |
-
primary_hue="
|
| 1069 |
-
secondary_hue="
|
| 1070 |
neutral_hue="slate",
|
| 1071 |
).set(
|
| 1072 |
body_background_fill="transparent",
|
|
@@ -1075,8 +1076,8 @@ def create_demo_interface() -> gr.Blocks:
|
|
| 1075 |
block_background_fill_dark="rgba(30, 41, 59, 0.9)",
|
| 1076 |
input_background_fill="rgba(30, 41, 59, 0.95)",
|
| 1077 |
input_background_fill_dark="rgba(30, 41, 59, 0.95)",
|
| 1078 |
-
button_primary_background_fill="linear-gradient(135deg, #
|
| 1079 |
-
button_primary_background_fill_hover="linear-gradient(135deg, #
|
| 1080 |
),
|
| 1081 |
) as demo:
|
| 1082 |
|
|
@@ -1258,7 +1259,7 @@ def create_demo_interface() -> gr.Blocks:
|
|
| 1258 |
<div class="how-to-use">
|
| 1259 |
<h3>💡 วิธีใช้งาน (Pipeline)</h3>
|
| 1260 |
<div style="background: rgba(15, 23, 42, 0.6); padding: 1rem; border-radius: 8px; margin-bottom: 1rem;">
|
| 1261 |
-
<p style="color: #
|
| 1262 |
<ol style="color: #94a3b8; line-height: 2;">
|
| 1263 |
<li>📤 <strong style="color: #f1f5f9;">อัพโหลดรูปภาพ</strong> - รูปรถที่มีป้ายทะเบียน</li>
|
| 1264 |
<li>🔍 <strong style="color: #f1f5f9;">กด "อ่านทะเบียน"</strong>
|
|
@@ -1282,7 +1283,7 @@ def create_demo_interface() -> gr.Blocks:
|
|
| 1282 |
<p style="margin-top: 1rem; color: #22c55e; font-size: 0.9rem;">
|
| 1283 |
✅ <strong>ระบบใหม่:</strong> บันทึกเฉพาะรูป Cropped + JSON ที่ตรวจสอบแล้ว (เหมาะสำหรับ Training)
|
| 1284 |
</p>
|
| 1285 |
-
<p style="margin-top: 0.5rem; color: #
|
| 1286 |
📝 <strong>Training Data:</strong> ไฟล์ที่บันทึกพร้อมใช้เป็น training data ทันที
|
| 1287 |
</p>
|
| 1288 |
<p style="margin-top: 0.5rem; color: #94a3b8; font-size: 0.9rem;">
|
|
@@ -1318,7 +1319,7 @@ def create_demo_interface() -> gr.Blocks:
|
|
| 1318 |
<li><strong>Step 2:</strong> Hurricane OCR v1 อ่านข้อความจากป้ายที่ crop แล้ว</li>
|
| 1319 |
<li><strong>Step 3:</strong> Extractor ดึงข้อมูลเป็น structured format (JSON/DataFrame)</li>
|
| 1320 |
</ol>
|
| 1321 |
-
<p style="margin-top: 0.5rem; color: #
|
| 1322 |
✅ <strong>Optimized:</strong> ตรวจจับป้ายครั้งเดียว แล้วส่ง cropped image ไปให้ OCR (ไม่ซ้ำซ้อน)
|
| 1323 |
</p>
|
| 1324 |
</li>
|
|
@@ -1337,10 +1338,10 @@ def create_demo_interface() -> gr.Blocks:
|
|
| 1337 |
<li>ป้ายทะเบียนรถแท็กซี่ / รถสาธารณะ</li>
|
| 1338 |
<li>รองรับทุกจังหวัดในประเทศไทย (77 จังหวัด)</li>
|
| 1339 |
</ul>
|
| 1340 |
-
<p style="margin-top: 1rem; color: #
|
| 1341 |
✅ <strong>Detection:</strong> HurricaneOD_beta สามารถตรวจจับป้ายทะเบียนจากรูปภาพรถได้อัตโนมัติ
|
| 1342 |
</p>
|
| 1343 |
-
<p style="margin-top: 0.5rem; color: #
|
| 1344 |
✅ <strong>OCR:</strong> Hurricane OCR อ่านข้อความได้แม่นยำสูง รองรับตัวอักษรไทยและตัวเลข
|
| 1345 |
</p>
|
| 1346 |
</div>
|
|
|
|
| 62 |
}
|
| 63 |
|
| 64 |
:root {
|
| 65 |
+
/* Hurricane theme: storm blue + amber */
|
| 66 |
+
--primary: #3b82f6;
|
| 67 |
+
--primary-light: #60a5fa;
|
| 68 |
+
--secondary: #f59e0b;
|
| 69 |
+
--accent: #f97316;
|
| 70 |
--success: #22c55e;
|
| 71 |
--error: #ef4444;
|
| 72 |
--warning: #eab308;
|
|
|
|
| 74 |
--bg-card: rgba(30, 41, 59, 0.9);
|
| 75 |
--bg-card-hover: rgba(51, 65, 85, 0.9);
|
| 76 |
--text-white: #ffffff;
|
| 77 |
+
--text-bright: #f1f5f9;
|
| 78 |
--text-light: #e2e8f0;
|
| 79 |
--text-muted: #94a3b8;
|
| 80 |
--border: rgba(71, 85, 105, 0.8);
|
|
|
|
| 120 |
font-family: 'Kanit', sans-serif;
|
| 121 |
font-size: 3.5rem;
|
| 122 |
font-weight: 700;
|
| 123 |
+
background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 50%, #f59e0b 100%);
|
| 124 |
-webkit-background-clip: text;
|
| 125 |
-webkit-text-fill-color: transparent;
|
| 126 |
background-clip: text;
|
|
|
|
| 129 |
}
|
| 130 |
|
| 131 |
.main-title p {
|
| 132 |
+
color: #cbd5e1;
|
| 133 |
font-size: 1.15rem;
|
| 134 |
font-weight: 500;
|
| 135 |
}
|
|
|
|
| 184 |
|
| 185 |
/* Primary Button */
|
| 186 |
.primary-btn {
|
| 187 |
+
background: linear-gradient(135deg, var(--primary) 0%, #2563eb 50%, var(--secondary) 100%) !important;
|
| 188 |
border: 1px solid rgba(255, 255, 255, 0.2) !important;
|
| 189 |
border-radius: 12px !important;
|
| 190 |
padding: 14px 36px !important;
|
|
|
|
| 192 |
font-size: 1.05rem !important;
|
| 193 |
color: white !important;
|
| 194 |
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
| 195 |
+
box-shadow: 0 4px 20px rgba(59, 130, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
|
| 196 |
text-transform: none !important;
|
| 197 |
backdrop-filter: blur(5px) !important;
|
| 198 |
-webkit-backdrop-filter: blur(5px) !important;
|
|
|
|
| 200 |
|
| 201 |
.primary-btn:hover {
|
| 202 |
transform: translateY(-3px) !important;
|
| 203 |
+
box-shadow: 0 8px 30px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3) !important;
|
| 204 |
}
|
| 205 |
|
| 206 |
/* Extract Button - Different color */
|
|
|
|
| 227 |
.edit-field input,
|
| 228 |
.edit-field textarea {
|
| 229 |
background: rgba(30, 41, 59, 0.95) !important;
|
| 230 |
+
border: 2px solid rgba(59, 130, 246, 0.4) !important;
|
| 231 |
color: #ffffff !important;
|
| 232 |
font-size: 1.1rem !important;
|
| 233 |
font-weight: 500 !important;
|
|
|
|
| 267 |
margin: 1rem 0 !important;
|
| 268 |
border-radius: 12px !important;
|
| 269 |
overflow: hidden !important;
|
| 270 |
+
border: 2px solid rgba(59, 130, 246, 0.6) !important;
|
| 271 |
+
box-shadow: 0 4px 20px rgba(59, 130, 246, 0.3) !important;
|
| 272 |
background: rgba(30, 41, 59, 0.9) !important;
|
| 273 |
backdrop-filter: blur(10px) !important;
|
| 274 |
-webkit-backdrop-filter: blur(10px) !important;
|
|
|
|
| 283 |
}
|
| 284 |
|
| 285 |
.cropped-plate label {
|
| 286 |
+
color: #60a5fa !important;
|
| 287 |
font-weight: 600 !important;
|
| 288 |
margin-bottom: 0.5rem !important;
|
| 289 |
}
|
|
|
|
| 302 |
|
| 303 |
.image-upload:hover {
|
| 304 |
border-color: var(--primary) !important;
|
| 305 |
+
background: rgba(59, 130, 246, 0.15) !important;
|
| 306 |
+
box-shadow: 0 8px 30px rgba(59, 130, 246, 0.2) !important;
|
| 307 |
}
|
| 308 |
|
| 309 |
/* Textbox / Textarea styling */
|
|
|
|
| 321 |
|
| 322 |
textarea:focus, input[type="text"]:focus {
|
| 323 |
border-color: var(--primary) !important;
|
| 324 |
+
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25) !important;
|
| 325 |
outline: none !important;
|
| 326 |
}
|
| 327 |
|
|
|
|
| 380 |
}
|
| 381 |
|
| 382 |
th {
|
| 383 |
+
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%) !important;
|
| 384 |
color: #ffffff !important;
|
| 385 |
font-weight: 700 !important;
|
| 386 |
padding: 14px 16px !important;
|
|
|
|
| 482 |
}
|
| 483 |
|
| 484 |
button[role="tab"][aria-selected="true"] {
|
| 485 |
+
background: linear-gradient(135deg, #3b82f6, #2563eb) !important;
|
| 486 |
color: #ffffff !important;
|
| 487 |
+
border-color: #3b82f6 !important;
|
| 488 |
font-weight: 700 !important;
|
| 489 |
box-shadow: 0 4px 15px rgba(14, 165, 233, 0.4) !important;
|
| 490 |
}
|
|
|
|
| 529 |
}
|
| 530 |
|
| 531 |
.footer a {
|
| 532 |
+
color: #3b82f6;
|
| 533 |
text-decoration: none;
|
| 534 |
font-weight: 600;
|
| 535 |
transition: color 0.2s ease;
|
|
|
|
| 597 |
}
|
| 598 |
|
| 599 |
.how-to-use strong {
|
| 600 |
+
color: #3b82f6 !important;
|
| 601 |
font-weight: 600 !important;
|
| 602 |
}
|
| 603 |
|
|
|
|
| 1066 |
title="AI OCR - Thai License Plate Recognition",
|
| 1067 |
css=CUSTOM_CSS,
|
| 1068 |
theme=gr.themes.Base(
|
| 1069 |
+
primary_hue="blue",
|
| 1070 |
+
secondary_hue="amber",
|
| 1071 |
neutral_hue="slate",
|
| 1072 |
).set(
|
| 1073 |
body_background_fill="transparent",
|
|
|
|
| 1076 |
block_background_fill_dark="rgba(30, 41, 59, 0.9)",
|
| 1077 |
input_background_fill="rgba(30, 41, 59, 0.95)",
|
| 1078 |
input_background_fill_dark="rgba(30, 41, 59, 0.95)",
|
| 1079 |
+
button_primary_background_fill="linear-gradient(135deg, #3b82f6, #f59e0b)",
|
| 1080 |
+
button_primary_background_fill_hover="linear-gradient(135deg, #60a5fa, #fbbf24)",
|
| 1081 |
),
|
| 1082 |
) as demo:
|
| 1083 |
|
|
|
|
| 1259 |
<div class="how-to-use">
|
| 1260 |
<h3>💡 วิธีใช้งาน (Pipeline)</h3>
|
| 1261 |
<div style="background: rgba(15, 23, 42, 0.6); padding: 1rem; border-radius: 8px; margin-bottom: 1rem;">
|
| 1262 |
+
<p style="color: #60a5fa; font-weight: 600; margin-bottom: 0.5rem;">📋 Process Flow:</p>
|
| 1263 |
<ol style="color: #94a3b8; line-height: 2;">
|
| 1264 |
<li>📤 <strong style="color: #f1f5f9;">อัพโหลดรูปภาพ</strong> - รูปรถที่มีป้ายทะเบียน</li>
|
| 1265 |
<li>🔍 <strong style="color: #f1f5f9;">กด "อ่านทะเบียน"</strong>
|
|
|
|
| 1283 |
<p style="margin-top: 1rem; color: #22c55e; font-size: 0.9rem;">
|
| 1284 |
✅ <strong>ระบบใหม่:</strong> บันทึกเฉพาะรูป Cropped + JSON ที่ตรวจสอบแล้ว (เหมาะสำหรับ Training)
|
| 1285 |
</p>
|
| 1286 |
+
<p style="margin-top: 0.5rem; color: #60a5fa; font-size: 0.9rem;">
|
| 1287 |
📝 <strong>Training Data:</strong> ไฟล์ที่บันทึกพร้อมใช้เป็น training data ทันที
|
| 1288 |
</p>
|
| 1289 |
<p style="margin-top: 0.5rem; color: #94a3b8; font-size: 0.9rem;">
|
|
|
|
| 1319 |
<li><strong>Step 2:</strong> Hurricane OCR v1 อ่านข้อความจากป้ายที่ crop แล้ว</li>
|
| 1320 |
<li><strong>Step 3:</strong> Extractor ดึงข้อมูลเป็น structured format (JSON/DataFrame)</li>
|
| 1321 |
</ol>
|
| 1322 |
+
<p style="margin-top: 0.5rem; color: #60a5fa; font-size: 0.85rem;">
|
| 1323 |
✅ <strong>Optimized:</strong> ตรวจจับป้ายครั้งเดียว แล้วส่ง cropped image ไปให้ OCR (ไม่ซ้ำซ้อน)
|
| 1324 |
</p>
|
| 1325 |
</li>
|
|
|
|
| 1338 |
<li>ป้ายทะเบียนรถแท็กซี่ / รถสาธารณะ</li>
|
| 1339 |
<li>รองรับทุกจังหวัดในประเทศไทย (77 จังหวัด)</li>
|
| 1340 |
</ul>
|
| 1341 |
+
<p style="margin-top: 1rem; color: #60a5fa; font-size: 0.9rem;">
|
| 1342 |
✅ <strong>Detection:</strong> HurricaneOD_beta สามารถตรวจจับป้ายทะเบียนจากรูปภาพรถได้อัตโนมัติ
|
| 1343 |
</p>
|
| 1344 |
+
<p style="margin-top: 0.5rem; color: #60a5fa; font-size: 0.9rem;">
|
| 1345 |
✅ <strong>OCR:</strong> Hurricane OCR อ่านข้อความได้แม่นยำสูง รองรับตัวอักษรไทยและตัวเลข
|
| 1346 |
</p>
|
| 1347 |
</div>
|