auraforllm commited on
Commit
018958d
·
verified ·
1 Parent(s): 10985e5

напиши сайт на aiogram-3 для анализа CT снимков легких, чтобы оно работало по такому пайплайну: 1) Пользователь загружает dicom файл 2) Он поступает на анализ с помощью нейросетевой модели 3) Пользователю выводится результат анализа. Нужно сохранять результаты для файлов в зависимости от сессии, авторизация пользователей не нужна.

Browse files
Files changed (2) hide show
  1. README.md +8 -5
  2. index.html +363 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Ct Lung Analyzer Ai
3
- emoji: 🐠
4
- colorFrom: indigo
5
- colorTo: blue
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: CT Lung Analyzer AI 🫁
3
+ colorFrom: gray
4
+ colorTo: pink
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://deepsite.hf.co).
index.html CHANGED
@@ -1,19 +1,364 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </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>CT Lung Analyzer AI</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
10
+ <script src="https://unpkg.com/feather-icons"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
12
+ <script>
13
+ tailwind.config = {
14
+ theme: {
15
+ extend: {
16
+ colors: {
17
+ primary: '#6366f1',
18
+ secondary: '#8b5cf6',
19
+ dark: '#0f172a',
20
+ light: '#f8fafc'
21
+ }
22
+ }
23
+ }
24
+ }
25
+ </script>
26
+ <style>
27
+ .glass-effect {
28
+ background: rgba(255, 255, 255, 0.1);
29
+ backdrop-filter: blur(10px);
30
+ -webkit-backdrop-filter: blur(10px);
31
+ }
32
+ .upload-area {
33
+ border: 2px dashed #8b5cf6;
34
+ transition: all 0.3s ease;
35
+ }
36
+ .upload-area:hover {
37
+ border-color: #6366f1;
38
+ background: rgba(99, 102, 241, 0.05);
39
+ }
40
+ .result-card {
41
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
42
+ }
43
+ .result-card:hover {
44
+ transform: translateY(-5px);
45
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
46
+ }
47
+ .progress-bar {
48
+ height: 6px;
49
+ background: linear-gradient(90deg, #6366f1, #8b5cf6);
50
+ }
51
+ </style>
52
+ </head>
53
+ <body class="bg-dark text-light min-h-screen">
54
+ <!-- Background Animation -->
55
+ <div id="vanta-bg" class="fixed top-0 left-0 w-full h-full z-0"></div>
56
+
57
+ <!-- Main Content -->
58
+ <div class="relative z-10 container mx-auto px-4 py-8">
59
+ <!-- Header -->
60
+ <header class="flex flex-col md:flex-row justify-between items-center mb-12 py-6 glass-effect rounded-2xl px-6">
61
+ <div class="flex items-center mb-4 md:mb-0">
62
+ <div class="bg-primary p-3 rounded-xl mr-4">
63
+ <i data-feather="activity" class="w-8 h-8"></i>
64
+ </div>
65
+ <div>
66
+ <h1 class="text-3xl font-bold">CT Lung Analyzer AI</h1>
67
+ <p class="text-purple-200">Advanced pulmonary pathology detection</p>
68
+ </div>
69
+ </div>
70
+ <div class="flex items-center space-x-4">
71
+ <button id="session-btn" class="bg-secondary hover:bg-purple-700 text-white px-4 py-2 rounded-lg flex items-center">
72
+ <i data-feather="user" class="mr-2"></i>
73
+ <span id="session-id">Session: XXXXXX</span>
74
+ </button>
75
+ </div>
76
+ </header>
77
+
78
+ <!-- Upload Section -->
79
+ <section class="mb-16">
80
+ <div class="glass-effect rounded-2xl p-8">
81
+ <h2 class="text-2xl font-bold mb-6 text-center">Upload DICOM Files</h2>
82
+ <div id="upload-area" class="upload-area rounded-xl p-12 text-center cursor-pointer">
83
+ <i data-feather="upload-cloud" class="w-16 h-16 mx-auto text-secondary mb-4"></i>
84
+ <h3 class="text-xl font-semibold mb-2">Drag & Drop DICOM Files</h3>
85
+ <p class="text-gray-300 mb-4">or click to browse your files</p>
86
+ <button class="bg-primary hover:bg-indigo-700 text-white px-6 py-3 rounded-lg font-medium">
87
+ Select Files
88
+ </button>
89
+ <input type="file" id="file-input" accept=".dcm" multiple class="hidden">
90
+ </div>
91
+ <div id="file-list" class="mt-6 hidden">
92
+ <h3 class="text-lg font-semibold mb-3">Selected Files:</h3>
93
+ <ul id="files-container" class="space-y-2"></ul>
94
+ </div>
95
+ <div class="mt-8 text-center">
96
+ <button id="analyze-btn" class="bg-gradient-to-r from-primary to-secondary hover:from-indigo-700 hover:to-purple-700 text-white px-8 py-4 rounded-xl font-bold text-lg shadow-lg transform hover:scale-105 transition-all duration-300">
97
+ Analyze CT Scans
98
+ </button>
99
+ </div>
100
+ </div>
101
+ </section>
102
+
103
+ <!-- Progress Section -->
104
+ <section id="progress-section" class="mb-16 hidden">
105
+ <div class="glass-effect rounded-2xl p-8">
106
+ <h2 class="text-2xl font-bold mb-6 text-center">Analysis in Progress</h2>
107
+ <div class="max-w-2xl mx-auto">
108
+ <div class="flex justify-between mb-2">
109
+ <span id="progress-text">Processing files...</span>
110
+ <span id="progress-percent">0%</span>
111
+ </div>
112
+ <div class="bg-gray-700 rounded-full h-4">
113
+ <div id="progress-bar" class="progress-bar rounded-full w-0"></div>
114
+ </div>
115
+ <div id="processing-files" class="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4"></div>
116
+ </div>
117
+ </div>
118
+ </section>
119
+
120
+ <!-- Results Section -->
121
+ <section id="results-section" class="hidden">
122
+ <div class="glass-effect rounded-2xl p-8 mb-8">
123
+ <h2 class="text-2xl font-bold mb-6 text-center">Analysis Results</h2>
124
+ <div id="results-container" class="grid grid-cols-1 lg:grid-cols-2 gap-6"></div>
125
+ </div>
126
+ </section>
127
+
128
+ <!-- Footer -->
129
+ <footer class="glass-effect rounded-2xl p-6 text-center text-gray-300">
130
+ <p>Powered by aiogram-3 | Advanced Neural Network Analysis | © 2023 CT Lung Analyzer AI</p>
131
+ </footer>
132
+ </div>
133
+
134
+ <script>
135
+ // Initialize Feather Icons
136
+ feather.replace();
137
+
138
+ // Initialize Vanta.js Background
139
+ VANTA.GLOBE({
140
+ el: "#vanta-bg",
141
+ mouseControls: true,
142
+ touchControls: true,
143
+ gyroControls: false,
144
+ minHeight: 200.00,
145
+ minWidth: 200.00,
146
+ scale: 1.00,
147
+ scaleMobile: 1.00,
148
+ color: 0x6366f1,
149
+ color2: 0x8b5cf6,
150
+ backgroundColor: 0x0f172a
151
+ });
152
+
153
+ // Session Management
154
+ function generateSessionId() {
155
+ return Math.random().toString(36).substring(2, 8).toUpperCase();
156
+ }
157
+
158
+ document.getElementById('session-id').textContent = 'Session: ' + generateSessionId();
159
+
160
+ // File Upload Handling
161
+ const uploadArea = document.getElementById('upload-area');
162
+ const fileInput = document.getElementById('file-input');
163
+ const fileList = document.getElementById('file-list');
164
+ const filesContainer = document.getElementById('files-container');
165
+ let selectedFiles = [];
166
+
167
+ uploadArea.addEventListener('click', () => {
168
+ fileInput.click();
169
+ });
170
+
171
+ uploadArea.addEventListener('dragover', (e) => {
172
+ e.preventDefault();
173
+ uploadArea.classList.add('bg-indigo-900/20');
174
+ });
175
+
176
+ uploadArea.addEventListener('dragleave', () => {
177
+ uploadArea.classList.remove('bg-indigo-900/20');
178
+ });
179
+
180
+ uploadArea.addEventListener('drop', (e) => {
181
+ e.preventDefault();
182
+ uploadArea.classList.remove('bg-indigo-900/20');
183
+ handleFiles(e.dataTransfer.files);
184
+ });
185
+
186
+ fileInput.addEventListener('change', () => {
187
+ handleFiles(fileInput.files);
188
+ });
189
+
190
+ function handleFiles(files) {
191
+ [...files].forEach(file => {
192
+ if (file.name.endsWith('.dcm')) {
193
+ selectedFiles.push(file);
194
+ }
195
+ });
196
+
197
+ updateFileList();
198
+ }
199
+
200
+ function updateFileList() {
201
+ if (selectedFiles.length > 0) {
202
+ fileList.classList.remove('hidden');
203
+ filesContainer.innerHTML = '';
204
+
205
+ selectedFiles.forEach((file, index) => {
206
+ const li = document.createElement('li');
207
+ li.className = 'flex justify-between items-center bg-dark/50 p-3 rounded-lg';
208
+ li.innerHTML = `
209
+ <span class="truncate mr-2">${file.name}</span>
210
+ <button onclick="removeFile(${index})" class="text-red-400 hover:text-red-300">
211
+ <i data-feather="x"></i>
212
+ </button>
213
+ `;
214
+ filesContainer.appendChild(li);
215
+ });
216
+
217
+ feather.replace();
218
+ } else {
219
+ fileList.classList.add('hidden');
220
+ }
221
+ }
222
+
223
+ function removeFile(index) {
224
+ selectedFiles.splice(index, 1);
225
+ updateFileList();
226
+ }
227
+
228
+ // Analysis Process
229
+ document.getElementById('analyze-btn').addEventListener('click', startAnalysis);
230
+
231
+ function startAnalysis() {
232
+ if (selectedFiles.length === 0) {
233
+ alert('Please select at least one DICOM file');
234
+ return;
235
+ }
236
+
237
+ // Show progress section
238
+ document.getElementById('progress-section').classList.remove('hidden');
239
+ document.getElementById('results-section').classList.add('hidden');
240
+
241
+ // Simulate analysis process
242
+ simulateAnalysis();
243
+ }
244
+
245
+ function simulateAnalysis() {
246
+ const progressBar = document.getElementById('progress-bar');
247
+ const progressText = document.getElementById('progress-text');
248
+ const progressPercent = document.getElementById('progress-percent');
249
+ const processingFiles = document.getElementById('processing-files');
250
+
251
+ // Reset progress
252
+ progressBar.style.width = '0%';
253
+ progressPercent.textContent = '0%';
254
+
255
+ // Display processing files
256
+ processingFiles.innerHTML = '';
257
+ selectedFiles.forEach((file, index) => {
258
+ const div = document.createElement('div');
259
+ div.className = 'bg-dark/50 p-4 rounded-lg';
260
+ div.innerHTML = `
261
+ <div class="flex items-center">
262
+ <div class="animate-spin rounded-full h-5 w-5 border-b-2 border-primary mr-3"></div>
263
+ <span class="truncate">${file.name}</span>
264
+ </div>
265
+ <div class="mt-2 h-2 bg-gray-700 rounded-full overflow-hidden">
266
+ <div id="file-progress-${index}" class="h-full bg-gradient-to-r from-primary to-secondary w-0"></div>
267
+ </div>
268
+ `;
269
+ processingFiles.appendChild(div);
270
+ });
271
+
272
+ // Simulate progress
273
+ let progress = 0;
274
+ const interval = setInterval(() => {
275
+ progress += Math.random() * 10;
276
+ if (progress >= 100) {
277
+ progress = 100;
278
+ clearInterval(interval);
279
+ setTimeout(showResults, 500);
280
+ }
281
+
282
+ progressBar.style.width = `${progress}%`;
283
+ progressPercent.textContent = `${Math.round(progress)}%`;
284
+ progressText.textContent = `Processing ${Math.min(selectedFiles.length, Math.ceil(progress / (100/selectedFiles.length)))} of ${selectedFiles.length} files`;
285
+
286
+ // Update individual file progress
287
+ selectedFiles.forEach((_, index) => {
288
+ const fileProgress = document.getElementById(`file-progress-${index}`);
289
+ if (fileProgress) {
290
+ const fileValue = Math.min(100, progress + (Math.random() * 20 - 10));
291
+ fileProgress.style.width = `${fileValue}%`;
292
+ }
293
+ });
294
+ }, 300);
295
+ }
296
+
297
+ function showResults() {
298
+ document.getElementById('progress-section').classList.add('hidden');
299
+ document.getElementById('results-section').classList.remove('hidden');
300
+
301
+ const resultsContainer = document.getElementById('results-container');
302
+ resultsContainer.innerHTML = '';
303
+
304
+ selectedFiles.forEach((file, index) => {
305
+ // Generate mock results
306
+ const anomalies = [
307
+ { name: "Pneumonia", confidence: Math.random() * 0.4 + 0.6 },
308
+ { name: "Nodule", confidence: Math.random() * 0.3 + 0.4 },
309
+ { name: "Emphysema", confidence: Math.random() * 0.2 + 0.3 }
310
+ ];
311
+
312
+ const resultCard = document.createElement('div');
313
+ resultCard.className = 'result-card bg-dark/50 rounded-2xl overflow-hidden';
314
+ resultCard.innerHTML = `
315
+ <div class="p-6">
316
+ <div class="flex justify-between items-start mb-4">
317
+ <h3 class="text-xl font-bold truncate mr-2">${file.name}</h3>
318
+ <span class="bg-primary/20 text-primary px-3 py-1 rounded-full text-sm">
319
+ Completed
320
+ </span>
321
+ </div>
322
+
323
+ <div class="mb-6 rounded-xl overflow-hidden">
324
+ <img src="http://static.photos/medical/640x360/${index + 1}" alt="CT Scan Visualization" class="w-full h-48 object-cover">
325
+ </div>
326
+
327
+ <div class="mb-6">
328
+ <h4 class="font-semibold mb-3">Detected Anomalies:</h4>
329
+ <div class="space-y-3">
330
+ ${anomalies.map(anomaly => `
331
+ <div>
332
+ <div class="flex justify-between mb-1">
333
+ <span>${anomaly.name}</span>
334
+ <span class="${anomaly.confidence > 0.7 ? 'text-red-400' : anomaly.confidence > 0.5 ? 'text-yellow-400' : 'text-green-400'}">
335
+ ${(anomaly.confidence * 100).toFixed(1)}%
336
+ </span>
337
+ </div>
338
+ <div class="h-2 bg-gray-700 rounded-full overflow-hidden">
339
+ <div class="h-full ${anomaly.confidence > 0.7 ? 'bg-red-500' : anomaly.confidence > 0.5 ? 'bg-yellow-500' : 'bg-green-500'}"
340
+ style="width: ${(anomaly.confidence * 100)}%"></div>
341
+ </div>
342
+ </div>
343
+ `).join('')}
344
+ </div>
345
+ </div>
346
+
347
+ <div class="flex space-x-3">
348
+ <button class="flex-1 bg-primary hover:bg-indigo-700 py-2 rounded-lg flex items-center justify-center">
349
+ <i data-feather="download" class="mr-2"></i> Download Report
350
+ </button>
351
+ <button class="flex-1 bg-secondary hover:bg-purple-700 py-2 rounded-lg flex items-center justify-center">
352
+ <i data-feather="eye" class="mr-2"></i> View Details
353
+ </button>
354
+ </div>
355
+ </div>
356
+ `;
357
+ resultsContainer.appendChild(resultCard);
358
+ });
359
+
360
+ feather.replace();
361
+ }
362
+ </script>
363
+ </body>
364
  </html>