Spaces:
Sleeping
Sleeping
Update streamlit_app.py
Browse files- streamlit_app.py +60 -77
streamlit_app.py
CHANGED
@@ -12,7 +12,7 @@ warnings.filterwarnings('ignore')
|
|
12 |
|
13 |
# Configure Streamlit
|
14 |
st.set_page_config(
|
15 |
-
page_title="Butterfly Identifier/Liblikamaja ID",
|
16 |
page_icon="🦋",
|
17 |
layout="wide"
|
18 |
)
|
@@ -261,65 +261,51 @@ transform = transforms.Compose([
|
|
261 |
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
|
262 |
])
|
263 |
|
264 |
-
def predict_butterfly(image):
|
265 |
"""Predict butterfly species from image"""
|
266 |
-
if image is None
|
267 |
return None, None
|
268 |
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
|
278 |
-
|
279 |
-
input_tensor = transform(image).unsqueeze(0)
|
280 |
|
281 |
-
|
282 |
-
|
283 |
-
output = model(input_tensor)
|
284 |
-
probabilities = torch.nn.functional.softmax(output[0], dim=0)
|
285 |
-
confidence, pred = torch.max(probabilities, 0)
|
286 |
-
|
287 |
-
# Get top 3 predictions for better debugging
|
288 |
-
top_probs, top_indices = torch.topk(probabilities, min(3, len(probabilities)))
|
289 |
-
|
290 |
-
if pred.item() < len(class_names):
|
291 |
-
predicted_class = class_names[pred.item()]
|
292 |
-
else:
|
293 |
-
predicted_class = f"Class_{pred.item()}"
|
294 |
-
|
295 |
-
# Debug info
|
296 |
-
print(f"Top predictions:")
|
297 |
-
for i, (prob, idx) in enumerate(zip(top_probs, top_indices)):
|
298 |
-
class_name = class_names[idx.item()] if idx.item() < len(class_names) else f"Class_{idx.item()}"
|
299 |
-
print(f" {i+1}. {class_name}: {prob.item():.3f}")
|
300 |
-
|
301 |
-
return predicted_class, confidence.item()
|
302 |
|
303 |
except Exception as e:
|
304 |
st.error(f"Prediction error: {str(e)}")
|
305 |
return None, None
|
306 |
|
307 |
# UI Code
|
308 |
-
st.title("🦋 Butterfly Identifier
|
309 |
-
st.write("Identify butterflies using your camera or by uploading an image!")
|
310 |
|
311 |
# Show model info
|
312 |
-
if model is not None:
|
313 |
-
st.info(f"📊 Model loaded: {len(class_names)} butterfly species recognized")
|
314 |
|
315 |
# Create tabs for different input methods
|
316 |
tab1, tab2 = st.tabs(["📷 Live Camera", "📁 Upload Image"])
|
317 |
|
318 |
with tab1:
|
319 |
-
st.header("Camera Capture")
|
320 |
st.write("Take a photo of a butterfly for identification!")
|
321 |
|
322 |
-
camera_photo = st.camera_input("Take a picture of a butterfly")
|
323 |
|
324 |
if camera_photo is not None:
|
325 |
try:
|
@@ -328,42 +314,40 @@ with tab1:
|
|
328 |
col1, col2 = st.columns(2)
|
329 |
|
330 |
with col1:
|
331 |
-
st.image(image, caption="Captured Image", use_column_width=True)
|
332 |
|
333 |
with col2:
|
334 |
-
with st.spinner("
|
335 |
predicted_class, confidence = predict_butterfly(image)
|
336 |
|
337 |
-
if predicted_class and confidence:
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
st.write(f"**About:** {butterfly_info[predicted_class]['description']}")
|
345 |
else:
|
346 |
-
st.warning("⚠️ **Low confidence prediction**")
|
347 |
-
st.info(f"Best guess: {predicted_class} ({confidence:.1%})")
|
348 |
-
st.markdown("**Tips for better results:**")
|
349 |
-
st.markdown("- Use better lighting")
|
350 |
-
st.markdown("-
|
351 |
-
st.markdown("-
|
352 |
-
st.markdown("- Avoid blurry or dark images")
|
353 |
else:
|
354 |
-
st.error("Unable to analyze image. Please try again.")
|
355 |
|
356 |
except Exception as e:
|
357 |
st.error(f"Error processing image: {str(e)}")
|
358 |
|
359 |
with tab2:
|
360 |
-
st.header("Upload Image")
|
361 |
-
st.write("Upload a clear photo of a butterfly for identification")
|
362 |
|
363 |
uploaded_file = st.file_uploader(
|
364 |
-
"Choose an image...",
|
365 |
type=["jpg", "jpeg", "png"],
|
366 |
-
help="Upload a clear photo of a butterfly"
|
367 |
)
|
368 |
|
369 |
if uploaded_file is not None:
|
@@ -381,33 +365,32 @@ with tab2:
|
|
381 |
predicted_class, confidence = predict_butterfly(image)
|
382 |
|
383 |
if predicted_class and confidence:
|
384 |
-
if confidence >= 0.
|
385 |
-
st.success(f"**
|
386 |
-
st.info(f"Confidence: {confidence:.2%}")
|
387 |
|
388 |
# Show additional info if available
|
389 |
if predicted_class in butterfly_info:
|
390 |
st.write(f"**About:** {butterfly_info[predicted_class]['description']}")
|
391 |
else:
|
392 |
-
st.warning("⚠️ **Low confidence prediction**")
|
393 |
-
st.info(f"Best guess: {predicted_class} ({confidence:.1%})")
|
394 |
-
st.markdown("**Tips for better results:**")
|
395 |
-
st.markdown("- Use better lighting")
|
396 |
-
st.markdown("-
|
397 |
-
st.markdown("-
|
398 |
-
st.markdown("- Avoid blurry or dark images")
|
399 |
else:
|
400 |
-
st.error("Unable to analyze image. Please try again.")
|
401 |
|
402 |
except Exception as e:
|
403 |
st.error(f"Error processing image: {str(e)}")
|
404 |
|
405 |
# Add footer
|
406 |
st.markdown("---")
|
407 |
-
st.markdown("### How to use:")
|
408 |
-
st.markdown("1. **Camera Capture**: Take a photo using your device camera")
|
409 |
-
st.markdown("2. **Upload Image**: Choose a butterfly photo from your device")
|
410 |
-
st.markdown("3. **Best Results**: Use clear, well-lit photos with the butterfly clearly visible")
|
411 |
|
412 |
# Debug info (only show if there are issues)
|
413 |
if st.checkbox("Show debug information"):
|
|
|
12 |
|
13 |
# Configure Streamlit
|
14 |
st.set_page_config(
|
15 |
+
page_title="Butterfly Identifier/ Liblikamaja ID",
|
16 |
page_icon="🦋",
|
17 |
layout="wide"
|
18 |
)
|
|
|
261 |
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
|
262 |
])
|
263 |
|
264 |
+
def predict_butterfly(image, threshold=0.5):
|
265 |
"""Predict butterfly species from image"""
|
266 |
+
if image is None:
|
267 |
return None, None
|
268 |
|
269 |
+
if isinstance(image, np.ndarray):
|
270 |
+
image = Image.fromarray(image)
|
271 |
+
if image.mode != 'RGB':
|
272 |
+
image = image.convert('RGB')
|
273 |
+
|
274 |
+
input_tensor = transform(image).unsqueeze(0)
|
275 |
+
|
276 |
+
with torch.no_grad():
|
277 |
+
output = model(input_tensor)
|
278 |
+
probabilities = torch.nn.functional.softmax(output[0], dim=0)
|
279 |
+
|
280 |
+
confidence, pred = torch.max(probabilities, 0)
|
281 |
+
if confidence.item() < threshold:
|
282 |
+
return None, confidence.item() # Too uncertain
|
283 |
|
284 |
+
predicted_class = class_names[pred.item()]
|
|
|
285 |
|
286 |
+
return predicted_class, confidence.item()
|
287 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
|
289 |
except Exception as e:
|
290 |
st.error(f"Prediction error: {str(e)}")
|
291 |
return None, None
|
292 |
|
293 |
# UI Code
|
294 |
+
st.title("🦋 Liblikamaja ID/ Butterfly Identifier")
|
295 |
+
st.write("Tuvasta liblikaid oma kaamera abil või laadi üles pilt!/ Identify butterflies using your camera or by uploading an image!")
|
296 |
|
297 |
# Show model info
|
298 |
+
#if model is not None:
|
299 |
+
#st.info(f"📊 Model loaded: {len(class_names)} butterfly species recognized")
|
300 |
|
301 |
# Create tabs for different input methods
|
302 |
tab1, tab2 = st.tabs(["📷 Live Camera", "📁 Upload Image"])
|
303 |
|
304 |
with tab1:
|
305 |
+
st.header("Kaamera jäädvustamine/ Camera Capture")
|
306 |
st.write("Take a photo of a butterfly for identification!")
|
307 |
|
308 |
+
camera_photo = st.camera_input("Pildista liblikat/ Take a picture of a butterfly")
|
309 |
|
310 |
if camera_photo is not None:
|
311 |
try:
|
|
|
314 |
col1, col2 = st.columns(2)
|
315 |
|
316 |
with col1:
|
317 |
+
st.image(image, caption="Captured Image/Jäädvustatud pilt", use_column_width=True)
|
318 |
|
319 |
with col2:
|
320 |
+
with st.spinner("Kujutise analüüsimine..."):
|
321 |
predicted_class, confidence = predict_butterfly(image)
|
322 |
|
323 |
+
if predicted_class and confidence >= 0.50:
|
324 |
+
st.success(f"**Liblika: {predicted_class}**")
|
325 |
+
#st.info(f"Confidence: {confidence:.2%}")
|
326 |
+
else:
|
327 |
+
st.warning("⚠️ **I don't know what butterfly this is.**")
|
328 |
+
#st.info(f"Confidence too low: {confidence:.1%}")
|
329 |
+
|
|
|
330 |
else:
|
331 |
+
st.warning("⚠️ **Low confidence prediction/ Madala usaldusväärsusega ennustus**")
|
332 |
+
#st.info(f"Best guess: {predicted_class} ({confidence:.1%})")
|
333 |
+
st.markdown("**Tips for better results/ Näpunäited paremate tulemuste saavutamiseks:**")
|
334 |
+
st.markdown("- Use better lighting/ Kasutage paremat valgustust")
|
335 |
+
st.markdown("- Ensure the butterfly is clearly visible/ Veenduge, et liblikas oleks selgelt nähtav")
|
336 |
+
st.markdown("- Avoid blurry or dark images/ Vältige uduseid või tumedaid pilte")
|
|
|
337 |
else:
|
338 |
+
st.error("Unable to analyze image. Please try again./ Pildi analüüsimine ebaõnnestus. Palun proovige uuesti.")
|
339 |
|
340 |
except Exception as e:
|
341 |
st.error(f"Error processing image: {str(e)}")
|
342 |
|
343 |
with tab2:
|
344 |
+
st.header("Upload Image/ Laadi pilt üles")
|
345 |
+
st.write("Upload a clear photo of a butterfly for identification/ Laadige üles liblika selge foto tuvastamiseks")
|
346 |
|
347 |
uploaded_file = st.file_uploader(
|
348 |
+
"Choose an image/ Valige pilt...",
|
349 |
type=["jpg", "jpeg", "png"],
|
350 |
+
help="Upload a clear photo of a butterfly/ Laadi üles selge foto liblikast"
|
351 |
)
|
352 |
|
353 |
if uploaded_file is not None:
|
|
|
365 |
predicted_class, confidence = predict_butterfly(image)
|
366 |
|
367 |
if predicted_class and confidence:
|
368 |
+
if confidence >= 0.50:
|
369 |
+
st.success(f"**liblikas: {predicted_class}**")
|
370 |
+
#st.info(f"Confidence: {confidence:.2%}")
|
371 |
|
372 |
# Show additional info if available
|
373 |
if predicted_class in butterfly_info:
|
374 |
st.write(f"**About:** {butterfly_info[predicted_class]['description']}")
|
375 |
else:
|
376 |
+
st.warning("⚠️ **Low confidence prediction/ Madala usaldusväärsusega ennustus**")
|
377 |
+
#st.info(f"Best guess: {predicted_class} ({confidence:.1%})")
|
378 |
+
st.markdown("**Tips for better results/ Näpunäited paremate tulemuste saavutamiseks:**")
|
379 |
+
st.markdown("- Use better lighting/ Kasutage paremat valgustust")
|
380 |
+
st.markdown("- Ensure the butterfly is clearly visible/ Veenduge, et liblikas oleks selgelt nähtav")
|
381 |
+
st.markdown("- Avoid blurry or dark images/ Vältige uduseid või tumedaid pilte")
|
|
|
382 |
else:
|
383 |
+
st.error("Unable to analyze image. Please try again./Pildi analüüsimine ebaõnnestus. Palun proovige uuesti.")
|
384 |
|
385 |
except Exception as e:
|
386 |
st.error(f"Error processing image: {str(e)}")
|
387 |
|
388 |
# Add footer
|
389 |
st.markdown("---")
|
390 |
+
st.markdown("### How to use/ Kuidas kasutada:")
|
391 |
+
st.markdown("1. **Camera Capture**: Take a photo using your device camera/ **Kaamera jäädvustamine**: Tehke foto oma seadme kaameraga")
|
392 |
+
st.markdown("2. **Upload Image**: Choose a butterfly photo from your device/ **Laadi pilt üles**: Vali oma seadmest liblika foto")
|
393 |
+
st.markdown("3. **Best Results**: Use clear, well-lit photos with the butterfly clearly visible/ **Parimad tulemused**: Kasutage selgeid ja hästi valgustatud fotosid, kus liblikas on selgelt nähtav.")
|
394 |
|
395 |
# Debug info (only show if there are issues)
|
396 |
if st.checkbox("Show debug information"):
|