Meenu047 commited on
Commit
3dffe7d
·
1 Parent(s): ee925c2

Add application file

Browse files
Files changed (3) hide show
  1. app.js +0 -314
  2. app.py +131 -0
  3. requirements.txt +6 -0
app.js DELETED
@@ -1,314 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { Upload, X, Loader2, Image } from 'lucide-react';
3
-
4
- export default function ModelTester() {
5
- const [file, setFile] = useState(null);
6
- const [preview, setPreview] = useState(null);
7
- const [loading, setLoading] = useState(false);
8
- const [result, setResult] = useState(null);
9
- const [error, setError] = useState(null);
10
- const [dragActive, setDragActive] = useState(false);
11
-
12
- // Your model ID from the repo
13
- const MODEL_ID = 'Meenu047/RGTB_Aerial_view_detection';
14
-
15
- const handleDrag = (e) => {
16
- e.preventDefault();
17
- e.stopPropagation();
18
- if (e.type === "dragenter" || e.type === "dragover") {
19
- setDragActive(true);
20
- } else if (e.type === "dragleave") {
21
- setDragActive(false);
22
- }
23
- };
24
-
25
- const handleDrop = (e) => {
26
- e.preventDefault();
27
- e.stopPropagation();
28
- setDragActive(false);
29
-
30
- if (e.dataTransfer.files && e.dataTransfer.files[0]) {
31
- handleFile(e.dataTransfer.files[0]);
32
- }
33
- };
34
-
35
- const handleChange = (e) => {
36
- e.preventDefault();
37
- if (e.target.files && e.target.files[0]) {
38
- handleFile(e.target.files[0]);
39
- }
40
- };
41
-
42
- const handleFile = (uploadedFile) => {
43
- const validTypes = ['image/jpeg', 'image/png', 'image/jpg', 'image/webp'];
44
-
45
- if (!validTypes.includes(uploadedFile.type)) {
46
- setError('Please upload a valid image file (JPEG, PNG, WebP)');
47
- return;
48
- }
49
-
50
- setFile(uploadedFile);
51
- setError(null);
52
- setResult(null);
53
-
54
- const reader = new FileReader();
55
- reader.onloadend = () => {
56
- setPreview(reader.result);
57
- };
58
- reader.readAsDataURL(uploadedFile);
59
- };
60
-
61
- const handlePredict = async () => {
62
- if (!file) {
63
- setError('Please upload an image first');
64
- return;
65
- }
66
-
67
- setLoading(true);
68
- setError(null);
69
- setResult(null);
70
-
71
- try {
72
- // Read file as blob
73
- const formData = new FormData();
74
- formData.append('file', file);
75
-
76
- const response = await fetch(
77
- `https://api-inference.huggingface.co/models/${MODEL_ID}`,
78
- {
79
- method: 'POST',
80
- body: file,
81
- }
82
- );
83
-
84
- if (!response.ok) {
85
- if (response.status === 503) {
86
- setError('Model is loading, please wait 20-30 seconds and try again');
87
- } else {
88
- const errorData = await response.json();
89
- throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
90
- }
91
- setLoading(false);
92
- return;
93
- }
94
-
95
- const data = await response.json();
96
- setResult(data);
97
- } catch (err) {
98
- setError(err.message || 'Failed to get prediction. Make sure the model is public and loaded.');
99
- } finally {
100
- setLoading(false);
101
- }
102
- };
103
-
104
- const clearImage = () => {
105
- setFile(null);
106
- setPreview(null);
107
- setResult(null);
108
- setError(null);
109
- };
110
-
111
- return (
112
- <div className="min-h-screen bg-gradient-to-br from-purple-50 via-blue-50 to-indigo-100 p-8">
113
- <div className="max-w-5xl mx-auto">
114
- <div className="bg-white rounded-2xl shadow-2xl p-8">
115
- <div className="flex items-center justify-between mb-6">
116
- <div className="flex items-center gap-3">
117
- <Image className="w-8 h-8 text-indigo-600" />
118
- <h1 className="text-3xl font-bold text-gray-800">
119
- RGTB Aerial View Detection
120
- </h1>
121
- </div>
122
- <div className="bg-indigo-100 px-4 py-2 rounded-lg">
123
- <span className="text-sm font-medium text-indigo-700">Model Ready</span>
124
- </div>
125
- </div>
126
-
127
- <div className="mb-6 p-4 bg-gray-50 rounded-lg border border-gray-200">
128
- <p className="text-sm text-gray-600">
129
- <span className="font-semibold">Model:</span> {MODEL_ID}
130
- </p>
131
- </div>
132
-
133
- {/* Drag & Drop Area */}
134
- {!preview ? (
135
- <div
136
- onDragEnter={handleDrag}
137
- onDragLeave={handleDrag}
138
- onDragOver={handleDrag}
139
- onDrop={handleDrop}
140
- className={`border-2 border-dashed rounded-xl p-16 text-center transition-all ${
141
- dragActive
142
- ? 'border-indigo-600 bg-indigo-50 scale-105'
143
- : 'border-gray-300 bg-gray-50 hover:border-indigo-400'
144
- }`}
145
- >
146
- <input
147
- type="file"
148
- id="file-upload"
149
- className="hidden"
150
- onChange={handleChange}
151
- accept="image/*"
152
- />
153
- <label
154
- htmlFor="file-upload"
155
- className="cursor-pointer flex flex-col items-center"
156
- >
157
- <div className="w-20 h-20 bg-indigo-100 rounded-full flex items-center justify-center mb-4">
158
- <Upload className="w-10 h-10 text-indigo-600" />
159
- </div>
160
- <p className="text-xl font-semibold text-gray-700 mb-2">
161
- Drop your aerial image here
162
- </p>
163
- <p className="text-sm text-gray-500 mb-4">
164
- or click to browse files
165
- </p>
166
- <div className="flex gap-2 text-xs text-gray-400">
167
- <span className="px-3 py-1 bg-white rounded-full border border-gray-200">JPEG</span>
168
- <span className="px-3 py-1 bg-white rounded-full border border-gray-200">PNG</span>
169
- <span className="px-3 py-1 bg-white rounded-full border border-gray-200">WebP</span>
170
- </div>
171
- </label>
172
- </div>
173
- ) : (
174
- <div className="space-y-4">
175
- {/* Image Preview */}
176
- <div className="relative rounded-xl overflow-hidden border-2 border-gray-200 bg-gray-900">
177
- <img
178
- src={preview}
179
- alt="Preview"
180
- className="w-full h-auto max-h-[500px] object-contain"
181
- />
182
- <button
183
- onClick={clearImage}
184
- className="absolute top-4 right-4 bg-red-500 text-white p-2 rounded-full hover:bg-red-600 transition-all shadow-lg hover:scale-110"
185
- >
186
- <X className="w-5 h-5" />
187
- </button>
188
- <div className="absolute bottom-4 left-4 bg-black/70 backdrop-blur-sm text-white px-4 py-2 rounded-lg text-sm">
189
- {file.name}
190
- </div>
191
- </div>
192
-
193
- {/* Predict Button */}
194
- <button
195
- onClick={handlePredict}
196
- disabled={loading}
197
- className="w-full bg-gradient-to-r from-indigo-600 to-purple-600 text-white py-4 rounded-xl font-semibold hover:from-indigo-700 hover:to-purple-700 transition-all disabled:from-gray-400 disabled:to-gray-400 disabled:cursor-not-allowed flex items-center justify-center gap-3 shadow-lg hover:shadow-xl transform hover:scale-[1.02]"
198
- >
199
- {loading ? (
200
- <>
201
- <Loader2 className="w-6 h-6 animate-spin" />
202
- <span>Analyzing Image...</span>
203
- </>
204
- ) : (
205
- <>
206
- <Image className="w-6 h-6" />
207
- <span>Run Detection</span>
208
- </>
209
- )}
210
- </button>
211
- </div>
212
- )}
213
-
214
- {/* Error Display */}
215
- {error && (
216
- <div className="mt-6 bg-red-50 border-l-4 border-red-500 rounded-lg p-4">
217
- <div className="flex items-start gap-3">
218
- <div className="flex-shrink-0">
219
- <svg className="w-5 h-5 text-red-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
220
- <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd"/>
221
- </svg>
222
- </div>
223
- <div>
224
- <p className="text-red-800 font-semibold">Error</p>
225
- <p className="text-red-700 text-sm mt-1">{error}</p>
226
- </div>
227
- </div>
228
- </div>
229
- )}
230
-
231
- {/* Results Display */}
232
- {result && (
233
- <div className="mt-6 bg-gradient-to-br from-green-50 to-emerald-50 border-2 border-green-200 rounded-xl p-6 shadow-lg">
234
- <h2 className="text-2xl font-bold text-gray-800 mb-4 flex items-center gap-2">
235
- <svg className="w-6 h-6 text-green-600" fill="currentColor" viewBox="0 0 20 20">
236
- <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd"/>
237
- </svg>
238
- Detection Results
239
- </h2>
240
-
241
- {/* Check if it's object detection format (with boxes) */}
242
- {Array.isArray(result) && result[0]?.box ? (
243
- <div className="space-y-3">
244
- <p className="text-gray-700 font-medium mb-3">
245
- Detected {result.length} object(s):
246
- </p>
247
- {result.map((item, idx) => (
248
- <div key={idx} className="bg-white rounded-lg p-4 shadow border border-gray-200">
249
- <div className="flex justify-between items-center mb-2">
250
- <span className="font-bold text-lg text-gray-800">{item.label}</span>
251
- <span className="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-semibold">
252
- {(item.score * 100).toFixed(1)}%
253
- </span>
254
- </div>
255
- <div className="text-xs text-gray-500 grid grid-cols-2 gap-2">
256
- <div>Box: x={Math.round(item.box.xmin)}, y={Math.round(item.box.ymin)}</div>
257
- <div>Size: {Math.round(item.box.xmax - item.box.xmin)}×{Math.round(item.box.ymax - item.box.ymin)}</div>
258
- </div>
259
- </div>
260
- ))}
261
- </div>
262
- ) : Array.isArray(result) && result[0]?.label ? (
263
- // Classification results
264
- <div className="space-y-3">
265
- {result.slice(0, 5).map((item, idx) => (
266
- <div key={idx} className="bg-white rounded-lg p-3 shadow">
267
- <div className="flex items-center gap-3 mb-2">
268
- <span className="font-semibold text-gray-700 min-w-[100px]">
269
- {item.label}
270
- </span>
271
- <div className="flex-1 bg-gray-200 rounded-full h-8 overflow-hidden">
272
- <div
273
- className="bg-gradient-to-r from-indigo-500 to-purple-500 h-full rounded-full flex items-center justify-end px-3 transition-all duration-500"
274
- style={{ width: `${(item.score * 100).toFixed(1)}%` }}
275
- >
276
- <span className="text-xs text-white font-bold">
277
- {(item.score * 100).toFixed(1)}%
278
- </span>
279
- </div>
280
- </div>
281
- </div>
282
- </div>
283
- ))}
284
- </div>
285
- ) : (
286
- // Raw JSON output
287
- <div className="bg-white rounded-lg p-4 shadow max-h-96 overflow-auto">
288
- <pre className="text-sm text-gray-800 whitespace-pre-wrap">
289
- {JSON.stringify(result, null, 2)}
290
- </pre>
291
- </div>
292
- )}
293
- </div>
294
- )}
295
- </div>
296
-
297
- {/* Info Card */}
298
- <div className="mt-6 bg-white rounded-xl shadow-lg p-6">
299
- <h3 className="font-bold text-gray-800 mb-3 text-lg">How to use:</h3>
300
- <ol className="list-decimal list-inside space-y-2 text-gray-600">
301
- <li>Drag and drop an aerial image or click to upload</li>
302
- <li>Click "Run Detection" to analyze the image</li>
303
- <li>View detected objects with confidence scores and bounding boxes</li>
304
- </ol>
305
- <div className="mt-4 p-3 bg-blue-50 rounded-lg border border-blue-200">
306
- <p className="text-sm text-blue-800">
307
- <strong>Note:</strong> First run may take 20-30 seconds while the model loads
308
- </p>
309
- </div>
310
- </div>
311
- </div>
312
- </div>
313
- );
314
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import AutoImageProcessor, AutoModelForObjectDetection
3
+ import torch
4
+ from PIL import Image, ImageDraw, ImageFont
5
+ import numpy as np
6
+
7
+ # Load your model
8
+ MODEL_ID = "Meenu047/RGTB_Aerial_view_detection"
9
+
10
+ print("Loading model...")
11
+ processor = AutoImageProcessor.from_pretrained(MODEL_ID)
12
+ model = AutoModelForObjectDetection.from_pretrained(MODEL_ID)
13
+ print("Model loaded successfully!")
14
+
15
+ def predict(image):
16
+ """
17
+ Run object detection on the input image
18
+ """
19
+ if image is None:
20
+ return None, "Please upload an image"
21
+
22
+ # Prepare image
23
+ inputs = processor(images=image, return_tensors="pt")
24
+
25
+ # Run inference
26
+ with torch.no_grad():
27
+ outputs = model(**inputs)
28
+
29
+ # Post-process results
30
+ target_sizes = torch.tensor([image.size[::-1]])
31
+ results = processor.post_process_object_detection(
32
+ outputs,
33
+ target_sizes=target_sizes,
34
+ threshold=0.5
35
+ )[0]
36
+
37
+ # Draw bounding boxes
38
+ draw = ImageDraw.Draw(image)
39
+
40
+ # Try to use a nice font, fallback to default if not available
41
+ try:
42
+ font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 20)
43
+ except:
44
+ font = ImageFont.load_default()
45
+
46
+ detections = []
47
+ colors = ['red', 'blue', 'green', 'yellow', 'purple', 'orange', 'pink', 'cyan']
48
+
49
+ for idx, (score, label, box) in enumerate(zip(results["scores"], results["labels"], results["boxes"])):
50
+ box = [round(i, 2) for i in box.tolist()]
51
+ confidence = round(score.item(), 3)
52
+ label_name = model.config.id2label[label.item()]
53
+
54
+ # Draw rectangle
55
+ color = colors[idx % len(colors)]
56
+ draw.rectangle(box, outline=color, width=3)
57
+
58
+ # Draw label
59
+ text = f"{label_name}: {confidence:.2f}"
60
+ text_bbox = draw.textbbox((box[0], box[1]), text, font=font)
61
+ draw.rectangle(text_bbox, fill=color)
62
+ draw.text((box[0], box[1]), text, fill='white', font=font)
63
+
64
+ detections.append({
65
+ "Label": label_name,
66
+ "Confidence": f"{confidence * 100:.1f}%",
67
+ "Box": f"({int(box[0])}, {int(box[1])}) - ({int(box[2])}, {int(box[3])})"
68
+ })
69
+
70
+ # Create results text
71
+ if len(detections) == 0:
72
+ results_text = "No objects detected with confidence > 50%"
73
+ else:
74
+ results_text = f"**Detected {len(detections)} object(s):**\n\n"
75
+ for i, det in enumerate(detections, 1):
76
+ results_text += f"**{i}. {det['Label']}**\n"
77
+ results_text += f" - Confidence: {det['Confidence']}\n"
78
+ results_text += f" - Location: {det['Box']}\n\n"
79
+
80
+ return image, results_text
81
+
82
+ # Create Gradio interface
83
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
84
+ gr.Markdown(
85
+ """
86
+ # 🚁 RGTB Aerial View Detection
87
+ Upload an aerial image to detect objects using the trained model.
88
+ """
89
+ )
90
+
91
+ with gr.Row():
92
+ with gr.Column():
93
+ input_image = gr.Image(
94
+ type="pil",
95
+ label="Upload Aerial Image",
96
+ height=400
97
+ )
98
+ predict_btn = gr.Button("🔍 Run Detection", variant="primary", size="lg")
99
+
100
+ with gr.Column():
101
+ output_image = gr.Image(
102
+ type="pil",
103
+ label="Detection Results",
104
+ height=400
105
+ )
106
+ output_text = gr.Markdown(label="Detected Objects")
107
+
108
+ gr.Examples(
109
+ examples=[], # Add example images here if you have any
110
+ inputs=input_image,
111
+ )
112
+
113
+ predict_btn.click(
114
+ fn=predict,
115
+ inputs=input_image,
116
+ outputs=[output_image, output_text]
117
+ )
118
+
119
+ gr.Markdown(
120
+ """
121
+ ### How to use:
122
+ 1. Upload or drag & drop an aerial image
123
+ 2. Click "Run Detection" button
124
+ 3. View the detected objects with bounding boxes and confidence scores
125
+
126
+ **Model:** `Meenu047/RGTB_Aerial_view_detection`
127
+ """
128
+ )
129
+
130
+ if __name__ == "__main__":
131
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio
2
+ transformers
3
+ torch
4
+ torchvision
5
+ pillow
6
+ numpy