Subh775 commited on
Commit
e08db9c
·
verified ·
1 Parent(s): 41c9fff

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +257 -257
index.html CHANGED
@@ -1,258 +1,258 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Tulsi Analytics — DETR & YOLO12</title>
7
- <style>
8
- :root {
9
- --primary-orange: #EA782D;
10
- --accent-orange: #FF7A5A;
11
- --dark-bg: #121212;
12
- --surface: #1E1E2E;
13
- --text: #E0E0E0;
14
- --border: rgba(255, 255, 255, 0.1);
15
- }
16
-
17
- body {
18
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
19
- background: var(--dark-bg);
20
- color: var(--text);
21
- margin: 0;
22
- padding: 20px;
23
- }
24
-
25
- .container {
26
- max-width: 1400px;
27
- margin: 0 auto;
28
- background: var(--surface);
29
- border-radius: 12px;
30
- border: 1px solid var(--border);
31
- overflow: hidden;
32
- }
33
-
34
- header {
35
- padding: 25px;
36
- text-align: center;
37
- border-bottom: 1px solid var(--border);
38
- background: rgba(0,0,0,0.2);
39
- }
40
-
41
- h1 { color: var(--primary-orange); margin: 0; font-weight: 500; }
42
-
43
- .layout {
44
- display: grid;
45
- grid-template-columns: 1fr 1fr;
46
- gap: 20px;
47
- padding: 20px;
48
- }
49
-
50
- @media (max-width: 1000px) {
51
- .layout { grid-template-columns: 1fr; }
52
- }
53
-
54
- .panel {
55
- background: rgba(0,0,0,0.15);
56
- padding: 20px;
57
- border-radius: 10px;
58
- }
59
-
60
- .image-view {
61
- width: 100%;
62
- height: 450px;
63
- background: #000;
64
- border-radius: 8px;
65
- display: flex;
66
- align-items: center;
67
- justify-content: center;
68
- margin-bottom: 15px;
69
- border: 1px solid var(--border);
70
- overflow: hidden;
71
- }
72
-
73
- img { max-width: 100%; max-height: 100%; object-fit: contain; }
74
-
75
- .controls {
76
- display: flex;
77
- flex-direction: column;
78
- gap: 15px;
79
- }
80
-
81
- .control-row {
82
- display: flex;
83
- align-items: center;
84
- justify-content: space-between;
85
- padding: 10px;
86
- background: rgba(255,255,255,0.03);
87
- border-radius: 6px;
88
- }
89
-
90
- .slider-group { padding: 10px; }
91
- input[type="range"] { width: 100%; accent-color: var(--primary-orange); }
92
-
93
- /* Toggle Switch */
94
- .switch {
95
- position: relative;
96
- display: inline-block;
97
- width: 44px;
98
- height: 22px;
99
- }
100
- .switch input { opacity: 0; width: 0; height: 0; }
101
- .slider {
102
- position: absolute;
103
- cursor: pointer;
104
- top: 0; left: 0; right: 0; bottom: 0;
105
- background-color: #444;
106
- transition: .4s;
107
- border-radius: 34px;
108
- }
109
- .slider:before {
110
- position: absolute;
111
- content: "";
112
- height: 16px; width: 16px;
113
- left: 3px; bottom: 3px;
114
- background-color: white;
115
- transition: .4s;
116
- border-radius: 50%;
117
- }
118
- input:checked + .slider { background-color: var(--primary-orange); }
119
- input:checked + .slider:before { transform: translateX(22px); }
120
-
121
- .predict-btn {
122
- background: var(--primary-orange);
123
- color: white;
124
- border: none;
125
- padding: 15px;
126
- border-radius: 8px;
127
- font-weight: 600;
128
- cursor: pointer;
129
- transition: 0.2s;
130
- width: 100%;
131
- }
132
- .predict-btn:hover { background: var(--accent-orange); }
133
- .predict-btn:disabled { opacity: 0.5; cursor: not-allowed; }
134
-
135
- .upload-box {
136
- border: 2px dashed var(--border);
137
- padding: 20px;
138
- text-align: center;
139
- cursor: pointer;
140
- margin-bottom: 15px;
141
- }
142
- </style>
143
- </head>
144
- <body>
145
-
146
- <div class="container">
147
- <header>
148
- <h1>Tulsi Disease Analyzer</h1>
149
- </header>
150
-
151
- <div class="layout">
152
- <div class="panel">
153
- <div class="upload-box" id="drop-zone">Click or Drop Image Here</div>
154
- <input type="file" id="file-input" hidden accept="image/*">
155
-
156
- <div class="image-view">
157
- <img id="input-preview" src="" style="display:none;">
158
- </div>
159
-
160
- <div class="controls">
161
- <div class="control-row">
162
- <span>Enable Segmentation</span>
163
- <label class="switch"><input type="checkbox" id="seg-enable" checked><span class="slider"></span></label>
164
- </div>
165
- <div class="slider-group">
166
- <label>Seg. Confidence: <span id="seg-val">0.25</span></label>
167
- <input type="range" id="seg-conf" min="5" max="95" value="25">
168
- </div>
169
- <div class="control-row">
170
- <span>Show Seg. Confidence</span>
171
- <label class="switch"><input type="checkbox" id="seg-show-conf"><span class="slider"></span></label>
172
- </div>
173
-
174
- <div class="control-row">
175
- <span>Enable Classification</span>
176
- <label class="switch"><input type="checkbox" id="cls-enable" checked><span class="slider"></span></label>
177
- </div>
178
- <div class="control-row">
179
- <span>Show Label</span>
180
- <label class="switch"><input type="checkbox" id="cls-show-label" checked><span class="slider"></span></label>
181
- </div>
182
- <div class="control-row">
183
- <span>Show Cls. Confidence</span>
184
- <label class="switch"><input type="checkbox" id="cls-show-conf" checked><span class="slider"></span></label>
185
- </div>
186
-
187
- <button id="predict-btn" class="predict-btn" disabled>Run Analysis</button>
188
- </div>
189
- </div>
190
-
191
- <div class="panel">
192
- <h3 style="margin-top:0;">Analysis Result</h3>
193
- <div class="image-view">
194
- <img id="output-preview" src="">
195
- </div>
196
- <div id="status">Status: Waiting for input</div>
197
- </div>
198
- </div>
199
- </div>
200
-
201
- <script>
202
- const fileInput = document.getElementById('file-input');
203
- const dropZone = document.getElementById('drop-zone');
204
- const inputImg = document.getElementById('input-preview');
205
- const outputImg = document.getElementById('output-preview');
206
- const predictBtn = document.getElementById('predict-btn');
207
- const segConf = document.getElementById('seg-conf');
208
- const segVal = document.getElementById('seg-val');
209
-
210
- segConf.oninput = () => segVal.innerText = (segConf.value / 100).toFixed(2);
211
-
212
- dropZone.onclick = () => fileInput.click();
213
- fileInput.onchange = (e) => handleFile(e.target.files[0]);
214
-
215
- function handleFile(file) {
216
- if (!file) return;
217
- const reader = new FileReader();
218
- reader.onload = (e) => {
219
- inputImg.src = e.target.result;
220
- inputImg.style.display = 'block';
221
- predictBtn.disabled = false;
222
- };
223
- reader.readAsDataURL(file);
224
- }
225
-
226
- predictBtn.onclick = async () => {
227
- predictBtn.disabled = true;
228
- predictBtn.innerText = "Processing...";
229
-
230
- const payload = {
231
- image: inputImg.src,
232
- seg_enabled: document.getElementById('seg-enable').checked,
233
- seg_conf: segConf.value / 100,
234
- seg_show_conf: document.getElementById('seg-show-conf').checked,
235
- cls_enabled: document.getElementById('cls-enable').checked,
236
- cls_show_conf: document.getElementById('cls-show-conf').checked,
237
- cls_show_label: document.getElementById('cls-show-label').checked
238
- };
239
-
240
- try {
241
- const resp = await fetch('/predict', {
242
- method: 'POST',
243
- headers: {'Content-Type': 'application/json'},
244
- body: JSON.stringify(payload)
245
- });
246
- const data = await resp.json();
247
- outputImg.src = data.annotated;
248
- document.getElementById('status').innerText = `Status: Detected ${data.count} leaves`;
249
- } catch (e) {
250
- alert("Error running inference");
251
- } finally {
252
- predictBtn.disabled = false;
253
- predictBtn.innerText = "Run Analysis";
254
- }
255
- };
256
- </script>
257
- </body>
258
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Tulsi Analytics — DETR & YOLO12</title>
7
+ <style>
8
+ :root {
9
+ --primary-orange: #EA782D;
10
+ --accent-orange: #FF7A5A;
11
+ --dark-bg: #121212;
12
+ --surface: #1E1E2E;
13
+ --text: #E0E0E0;
14
+ --border: rgba(255, 255, 255, 0.1);
15
+ }
16
+
17
+ body {
18
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
19
+ background: var(--dark-bg);
20
+ color: var(--text);
21
+ margin: 0;
22
+ padding: 20px;
23
+ }
24
+
25
+ .container {
26
+ max-width: 1400px;
27
+ margin: 0 auto;
28
+ background: var(--surface);
29
+ border-radius: 12px;
30
+ border: 1px solid var(--border);
31
+ overflow: hidden;
32
+ }
33
+
34
+ header {
35
+ padding: 25px;
36
+ text-align: center;
37
+ border-bottom: 1px solid var(--border);
38
+ background: rgba(0,0,0,0.2);
39
+ }
40
+
41
+ h1 { color: var(--primary-orange); margin: 0; font-weight: 500; }
42
+
43
+ .layout {
44
+ display: grid;
45
+ grid-template-columns: 1fr 1fr;
46
+ gap: 20px;
47
+ padding: 20px;
48
+ }
49
+
50
+ @media (max-width: 1000px) {
51
+ .layout { grid-template-columns: 1fr; }
52
+ }
53
+
54
+ .panel {
55
+ background: rgba(0,0,0,0.15);
56
+ padding: 20px;
57
+ border-radius: 10px;
58
+ }
59
+
60
+ .image-view {
61
+ width: 100%;
62
+ height: 450px;
63
+ background: #000;
64
+ border-radius: 8px;
65
+ display: flex;
66
+ align-items: center;
67
+ justify-content: center;
68
+ margin-bottom: 15px;
69
+ border: 1px solid var(--border);
70
+ overflow: hidden;
71
+ }
72
+
73
+ img { max-width: 100%; max-height: 100%; object-fit: contain; }
74
+
75
+ .controls {
76
+ display: flex;
77
+ flex-direction: column;
78
+ gap: 15px;
79
+ }
80
+
81
+ .control-row {
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: space-between;
85
+ padding: 10px;
86
+ background: rgba(255,255,255,0.03);
87
+ border-radius: 6px;
88
+ }
89
+
90
+ .slider-group { padding: 10px; }
91
+ input[type="range"] { width: 100%; accent-color: var(--primary-orange); }
92
+
93
+ /* Toggle Switch */
94
+ .switch {
95
+ position: relative;
96
+ display: inline-block;
97
+ width: 44px;
98
+ height: 22px;
99
+ }
100
+ .switch input { opacity: 0; width: 0; height: 0; }
101
+ .slider {
102
+ position: absolute;
103
+ cursor: pointer;
104
+ top: 0; left: 0; right: 0; bottom: 0;
105
+ background-color: #444;
106
+ transition: .4s;
107
+ border-radius: 34px;
108
+ }
109
+ .slider:before {
110
+ position: absolute;
111
+ content: "";
112
+ height: 16px; width: 16px;
113
+ left: 3px; bottom: 3px;
114
+ background-color: white;
115
+ transition: .4s;
116
+ border-radius: 50%;
117
+ }
118
+ input:checked + .slider { background-color: var(--primary-orange); }
119
+ input:checked + .slider:before { transform: translateX(22px); }
120
+
121
+ .predict-btn {
122
+ background: var(--primary-orange);
123
+ color: white;
124
+ border: none;
125
+ padding: 15px;
126
+ border-radius: 8px;
127
+ font-weight: 600;
128
+ cursor: pointer;
129
+ transition: 0.2s;
130
+ width: 100%;
131
+ }
132
+ .predict-btn:hover { background: var(--accent-orange); }
133
+ .predict-btn:disabled { opacity: 0.5; cursor: not-allowed; }
134
+
135
+ .upload-box {
136
+ border: 2px dashed var(--border);
137
+ padding: 20px;
138
+ text-align: center;
139
+ cursor: pointer;
140
+ margin-bottom: 15px;
141
+ }
142
+ </style>
143
+ </head>
144
+ <body>
145
+
146
+ <div class="container">
147
+ <header>
148
+ <h1>Tulsi Disease Analysis</h1>
149
+ </header>
150
+
151
+ <div class="layout">
152
+ <div class="panel">
153
+ <div class="upload-box" id="drop-zone">Click/Drop Image</div>
154
+ <input type="file" id="file-input" hidden accept="image/*">
155
+
156
+ <div class="image-view">
157
+ <img id="input-preview" src="" style="display:none;">
158
+ </div>
159
+
160
+ <div class="controls">
161
+ <div class="control-row">
162
+ <span>Enable Segmentation</span>
163
+ <label class="switch"><input type="checkbox" id="seg-enable" checked><span class="slider"></span></label>
164
+ </div>
165
+ <div class="slider-group">
166
+ <label>Seg. Confidence: <span id="seg-val">0.25</span></label>
167
+ <input type="range" id="seg-conf" min="5" max="95" value="25">
168
+ </div>
169
+ <div class="control-row">
170
+ <span>Show Seg. Confidence</span>
171
+ <label class="switch"><input type="checkbox" id="seg-show-conf"><span class="slider"></span></label>
172
+ </div>
173
+
174
+ <div class="control-row">
175
+ <span>Enable Classification</span>
176
+ <label class="switch"><input type="checkbox" id="cls-enable" checked><span class="slider"></span></label>
177
+ </div>
178
+ <div class="control-row">
179
+ <span>Show Label</span>
180
+ <label class="switch"><input type="checkbox" id="cls-show-label" checked><span class="slider"></span></label>
181
+ </div>
182
+ <div class="control-row">
183
+ <span>Show Cls. Confidence</span>
184
+ <label class="switch"><input type="checkbox" id="cls-show-conf" checked><span class="slider"></span></label>
185
+ </div>
186
+
187
+ <button id="predict-btn" class="predict-btn" disabled>Run Analysis</button>
188
+ </div>
189
+ </div>
190
+
191
+ <div class="panel">
192
+ <h3 style="margin-top:0;">Overlay Result</h3>
193
+ <div class="image-view">
194
+ <img id="output-preview" src="">
195
+ </div>
196
+ <div id="status">Status: Waiting for input</div>
197
+ </div>
198
+ </div>
199
+ </div>
200
+
201
+ <script>
202
+ const fileInput = document.getElementById('file-input');
203
+ const dropZone = document.getElementById('drop-zone');
204
+ const inputImg = document.getElementById('input-preview');
205
+ const outputImg = document.getElementById('output-preview');
206
+ const predictBtn = document.getElementById('predict-btn');
207
+ const segConf = document.getElementById('seg-conf');
208
+ const segVal = document.getElementById('seg-val');
209
+
210
+ segConf.oninput = () => segVal.innerText = (segConf.value / 100).toFixed(2);
211
+
212
+ dropZone.onclick = () => fileInput.click();
213
+ fileInput.onchange = (e) => handleFile(e.target.files[0]);
214
+
215
+ function handleFile(file) {
216
+ if (!file) return;
217
+ const reader = new FileReader();
218
+ reader.onload = (e) => {
219
+ inputImg.src = e.target.result;
220
+ inputImg.style.display = 'block';
221
+ predictBtn.disabled = false;
222
+ };
223
+ reader.readAsDataURL(file);
224
+ }
225
+
226
+ predictBtn.onclick = async () => {
227
+ predictBtn.disabled = true;
228
+ predictBtn.innerText = "Processing...";
229
+
230
+ const payload = {
231
+ image: inputImg.src,
232
+ seg_enabled: document.getElementById('seg-enable').checked,
233
+ seg_conf: segConf.value / 100,
234
+ seg_show_conf: document.getElementById('seg-show-conf').checked,
235
+ cls_enabled: document.getElementById('cls-enable').checked,
236
+ cls_show_conf: document.getElementById('cls-show-conf').checked,
237
+ cls_show_label: document.getElementById('cls-show-label').checked
238
+ };
239
+
240
+ try {
241
+ const resp = await fetch('/predict', {
242
+ method: 'POST',
243
+ headers: {'Content-Type': 'application/json'},
244
+ body: JSON.stringify(payload)
245
+ });
246
+ const data = await resp.json();
247
+ outputImg.src = data.annotated;
248
+ document.getElementById('status').innerText = `Status: Detected ${data.count} leaves`;
249
+ } catch (e) {
250
+ alert("Error running inference");
251
+ } finally {
252
+ predictBtn.disabled = false;
253
+ predictBtn.innerText = "Run Analysis";
254
+ }
255
+ };
256
+ </script>
257
+ </body>
258
  </html>