SavlonBhai commited on
Commit
aac8470
·
verified ·
1 Parent(s): f996c5a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -34
app.py CHANGED
@@ -1,44 +1,136 @@
 
 
 
 
 
1
  import gradio as gr
2
  from ultralytics import YOLO
3
  from PIL import Image
4
  import numpy as np
 
 
 
 
5
 
6
- # Load your pretrained YOLOv8 model (replace with your model path if customized)
7
- model = YOLO("yolov8n.pt") # Using tiny YOLOv8 pretrained weights for example
8
-
9
- # Define the class names according to your trained model classes
10
- class_names = ["butterfly", "chicken", "elephant", "horse", "spider", "squirrel"]
 
 
 
 
 
 
 
11
 
12
- def classify_animal(image):
13
- # Convert numpy array to PIL Image
14
- if isinstance(image, np.ndarray):
15
- image = Image.fromarray(image)
16
- # YOLO expects numpy array input, convert back to np array
17
- img_np = np.array(image)
 
18
 
19
- # Perform prediction
20
- results = model(img_np)
 
 
21
 
22
- # Extract top prediction
23
- if results and len(results) > 0:
24
- boxes = results[0].boxes
25
- if boxes is not None and len(boxes) > 0:
26
- # Get the highest confidence prediction
27
- best_box = boxes[0]
28
- conf = best_box.conf[0].item()
29
- class_id = int(best_box.cls[0].item())
30
- class_name = class_names[class_id] if class_id < len(class_names) else "Unknown"
31
- return f"Predicted: {class_name} (Confidence: {conf:.2f})"
32
- return "No animal detected."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- # Build Gradio interface
35
- iface = gr.Interface(
36
- fn=classify_animal,
37
- inputs=gr.Image(type="numpy", label="Upload Animal Image"),
38
- outputs="text",
39
- title="Real-Time Animal Type Classification",
40
- description="Upload an image of an animal to classify it among butterfly, chicken, elephant, horse, spider, and squirrel."
41
- )
42
 
43
- if __name__ == "__main__":
44
- iface.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Animal Type Classification App
3
+ A robust Gradio application for classifying animals using YOLOv8
4
+ """
5
+
6
  import gradio as gr
7
  from ultralytics import YOLO
8
  from PIL import Image
9
  import numpy as np
10
+ import logging
11
+ import sys
12
+ import os
13
+ from typing import Optional, Tuple
14
 
15
+ # ============================================================================
16
+ # LOGGING CONFIGURATION
17
+ # ============================================================================
18
+ logging.basicConfig(
19
+ level=logging.INFO,
20
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
21
+ handlers=[
22
+ logging.FileHandler('animal_classifier.log'),
23
+ logging.StreamHandler(sys.stdout)
24
+ ]
25
+ )
26
+ logger = logging.getLogger(__name__)
27
 
28
+ # ============================================================================
29
+ # CONFIGURATION
30
+ # ============================================================================
31
+ MODEL_PATH = "best_animal_classifier.pt"
32
+ CLASS_NAMES = ["butterfly", "chicken", "elephant", "horse", "spider", "squirrel"]
33
+ CONFIDENCE_THRESHOLD = 0.5
34
+ MIN_DETECTIONS = 1
35
 
36
+ # ============================================================================
37
+ # GLOBAL MODEL VARIABLE
38
+ # ============================================================================
39
+ model = None
40
 
41
+ # ============================================================================
42
+ # MODEL INITIALIZATION WITH EXCEPTION HANDLING
43
+ # ============================================================================
44
+ def load_model() -> Optional[YOLO]:
45
+ """
46
+ Load the YOLO model with comprehensive error handling.
47
+
48
+ Returns:
49
+ YOLO: Loaded model object or None if loading fails
50
+ """
51
+ global model
52
+
53
+ try:
54
+ logger.info(f"Attempting to load model from: {MODEL_PATH}")
55
+
56
+ # Check if model file exists
57
+ if not os.path.exists(MODEL_PATH):
58
+ logger.error(f"Model file not found at: {MODEL_PATH}")
59
+ raise FileNotFoundError(
60
+ f"Model file '{MODEL_PATH}' does not exist. "
61
+ f"Please ensure the file is in the correct location."
62
+ )
63
+
64
+ # Check if file has read permissions
65
+ if not os.access(MODEL_PATH, os.R_OK):
66
+ logger.error(f"No read permission for model file: {MODEL_PATH}")
67
+ raise PermissionError(
68
+ f"No read permission for model file: {MODEL_PATH}"
69
+ )
70
+
71
+ # Load the model
72
+ model = YOLO(MODEL_PATH)
73
+ logger.info("✅ Model loaded successfully!")
74
+
75
+ return model
76
+
77
+ except FileNotFoundError as e:
78
+ logger.error(f"FileNotFoundError: {e}")
79
+ return None
80
+
81
+ except PermissionError as e:
82
+ logger.error(f"PermissionError: {e}")
83
+ return None
84
+
85
+ except Exception as e:
86
+ logger.error(f"Unexpected error loading model: {type(e).__name__}: {e}")
87
+ return None
88
 
 
 
 
 
 
 
 
 
89
 
90
+ # ============================================================================
91
+ # CLASSIFICATION FUNCTION WITH ROBUST ERROR HANDLING
92
+ # ============================================================================
93
+ def classify_animal(image: Optional[np.ndarray]) -> str:
94
+ """
95
+ Classify an animal in the provided image using YOLOv8.
96
+
97
+ Args:
98
+ image (Optional[np.ndarray]): Input image as numpy array or PIL Image
99
+
100
+ Returns:
101
+ str: Classification result with confidence score or error message
102
+ """
103
+
104
+ try:
105
+ # ========== INPUT VALIDATION ==========
106
+ if image is None:
107
+ logger.warning("No image provided")
108
+ return "❌ Error: No image provided. Please upload an image."
109
+
110
+ logger.info("Image received for classification")
111
+
112
+ # ========== MODEL AVAILABILITY CHECK ==========
113
+ if model is None:
114
+ logger.error("Model is not loaded")
115
+ return "❌ Critical Error: Model not loaded. Please restart the application."
116
+
117
+ # ========== IMAGE TYPE CONVERSION ==========
118
+ try:
119
+ if isinstance(image, np.ndarray):
120
+ # Validate numpy array dimensions
121
+ if image.ndim not in [2, 3, 4]:
122
+ logger.error(f"Invalid image dimensions: {image.ndim}")
123
+ return "❌ Error: Invalid image dimensions. Expected 2D, 3D, or 4D array."
124
+
125
+ # Validate data type
126
+ if not np.issubdtype(image.dtype, np.integer):
127
+ logger.warning(f"Unexpected image dtype: {image.dtype}, attempting conversion")
128
+ image = image.astype('uint8')
129
+
130
+ # Convert to PIL Image
131
+ image_pil = Image.fromarray(image.astype('uint8'))
132
+ logger.debug("Converted numpy array to PIL Image")
133
+
134
+ elif isinstance(image, Image.Image):
135
+ image_pil = image
136
+ lo