Sehajbir commited on
Commit
e363f16
·
verified ·
1 Parent(s): 5867ea4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -103
app.py CHANGED
@@ -1,5 +1,3 @@
1
- from flask import Flask, render_template, request, redirect, url_for, jsonify, flash
2
- from werkzeug.utils import secure_filename
3
  from ultralytics import YOLO
4
  import cv2
5
  import os
@@ -7,21 +5,20 @@ import numpy as np
7
  import uuid
8
  import time
9
  import logging
10
-
11
- app = Flask(__name__)
12
- app.secret_key = os.urandom(24)
13
- app.config['UPLOAD_FOLDER'] = 'static/uploads'
14
- app.config['RESULT_FOLDER'] = 'static/results'
15
- app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'webp', 'gif'}
16
- app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16 MB max upload
17
 
18
  # Configure logging
19
  logging.basicConfig(level=logging.INFO)
20
  logger = logging.getLogger(__name__)
21
 
22
  # Create folders if they don't exist
23
- os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
24
- os.makedirs(app.config['RESULT_FOLDER'], exist_ok=True)
 
 
 
 
 
25
 
26
  # Load the model
27
  try:
@@ -31,20 +28,17 @@ except Exception as e:
31
  logger.error(f"Error loading model: {str(e)}")
32
  model = None
33
 
34
- def allowed_file(filename):
35
- return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
36
-
37
- def count_fruits(image_path, model, conf=0.25):
38
  """
39
- Runs inference on the image, counts fruits per class, and returns both the counts and results.
40
  """
41
  try:
42
  # Run inference
43
- results = model.predict(image_path, conf=conf)[0]
44
-
45
  # Initialize fruit counter dictionary
46
  fruit_counts = {}
47
-
48
  # Iterate over each detected box
49
  for box in results.boxes:
50
  class_id = int(box.cls)
@@ -60,102 +54,81 @@ def count_fruits(image_path, model, conf=0.25):
60
  class_with_confidence = f"{class_name}"
61
 
62
  fruit_counts[class_with_confidence] = fruit_counts.get(class_with_confidence, 0) + 1
63
-
64
- return fruit_counts, results, None
65
- except Exception as e:
66
- logger.error(f"Error in fruit detection: {str(e)}")
67
- return {}, None, str(e)
68
-
69
- @app.route('/')
70
- def index():
71
- return render_template('index.html')
72
-
73
- @app.route('/upload', methods=['POST'])
74
- def upload_file():
75
- if 'file' not in request.files:
76
- return jsonify({'error': 'No file part'}), 400
77
-
78
- file = request.files['file']
79
-
80
- if file.filename == '':
81
- return jsonify({'error': 'No file selected'}), 400
82
-
83
- if not allowed_file(file.filename):
84
- return jsonify({'error': 'File type not allowed'}), 400
85
-
86
- try:
87
- # Generate a unique filename
88
- unique_filename = f"{uuid.uuid4()}_{secure_filename(file.filename)}"
89
- file_path = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)
90
- file.save(file_path)
91
 
92
- # Return the filename so the frontend can use it for the next request
93
- return jsonify({
94
- 'status': 'success',
95
- 'filename': unique_filename,
96
- 'message': 'File uploaded successfully'
97
- })
98
 
 
99
  except Exception as e:
100
- logger.error(f"Error uploading file: {str(e)}")
101
- return jsonify({'error': str(e)}), 500
102
 
103
- @app.route('/process', methods=['POST'])
104
- def process_image():
105
- data = request.json
106
- filename = data.get('filename')
107
- conf_threshold = float(data.get('confidence', 0.25))
108
-
109
- if not filename:
110
- return jsonify({'error': 'No filename provided'}), 400
111
-
112
- file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
113
-
114
- if not os.path.exists(file_path):
115
- return jsonify({'error': 'File not found'}), 404
116
 
117
  try:
118
- # Process the image
119
  start_time = time.time()
120
- counts, results, error = count_fruits(file_path, model, conf=conf_threshold)
 
121
 
122
- if error:
123
- return jsonify({'error': error}), 500
124
 
125
- # Generate and save result image
126
- results_image = results.plot() # This returns a numpy array with the detections drawn
127
- result_filename = f"result_{filename}"
128
- result_path = os.path.join(app.config['RESULT_FOLDER'], result_filename)
 
 
 
 
 
 
129
 
130
- # Save the result image
131
- cv2.imwrite(result_path, results_image)
 
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
- # Get processing stats from results
134
- processing_time = results.speed
135
- total_time = time.time() - start_time
 
 
136
 
137
- return jsonify({
138
- 'status': 'success',
139
- 'counts': counts,
140
- 'original_image': filename,
141
- 'result_image': result_filename,
142
- 'processing_time': {
143
- 'preprocess': processing_time.get('preprocess', 'N/A'),
144
- 'inference': processing_time.get('inference', 'N/A'),
145
- 'postprocess': processing_time.get('postprocess', 'N/A'),
146
- 'total': round(total_time * 1000, 2)
147
- }
148
- })
149
 
150
- except Exception as e:
151
- logger.error(f"Error processing image: {str(e)}")
152
- return jsonify({'error': str(e)}), 500
 
153
 
154
- # Health check endpoint
155
- @app.route('/health')
156
- def health_check():
157
- return jsonify({'status': 'ok', 'model_loaded': model is not None})
158
 
159
- if __name__ == '__main__':
160
- port = int(os.environ.get('PORT', 10000))
161
- app.run(host='0.0.0.0', port=port, debug=True)
 
 
 
1
  from ultralytics import YOLO
2
  import cv2
3
  import os
 
5
  import uuid
6
  import time
7
  import logging
8
+ import gradio as gr
 
 
 
 
 
 
9
 
10
  # Configure logging
11
  logging.basicConfig(level=logging.INFO)
12
  logger = logging.getLogger(__name__)
13
 
14
  # Create folders if they don't exist
15
+ UPLOAD_FOLDER = 'static/uploads'
16
+ RESULT_FOLDER = 'static/results'
17
+ ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'webp', 'gif'}
18
+ MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16 MB max upload
19
+
20
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
21
+ os.makedirs(RESULT_FOLDER, exist_ok=True)
22
 
23
  # Load the model
24
  try:
 
28
  logger.error(f"Error loading model: {str(e)}")
29
  model = None
30
 
31
+ def count_fruits(image, conf=0.25):
 
 
 
32
  """
33
+ Runs inference on the image, counts fruits per class, and returns both the counts and visualized results.
34
  """
35
  try:
36
  # Run inference
37
+ results = model.predict(image, conf=conf)[0]
38
+
39
  # Initialize fruit counter dictionary
40
  fruit_counts = {}
41
+
42
  # Iterate over each detected box
43
  for box in results.boxes:
44
  class_id = int(box.cls)
 
54
  class_with_confidence = f"{class_name}"
55
 
56
  fruit_counts[class_with_confidence] = fruit_counts.get(class_with_confidence, 0) + 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
+ # Generate result image with detections
59
+ results_image = results.plot()
60
+
61
+ # Create count summary
62
+ count_summary = "\n".join([f"{fruit}: {count}" for fruit, count in fruit_counts.items()])
 
63
 
64
+ return results_image, count_summary
65
  except Exception as e:
66
+ logger.error(f"Error in fruit detection: {str(e)}")
67
+ return None, f"Error processing image: {str(e)}"
68
 
69
+ def process_image(image, confidence):
70
+ """
71
+ Process the uploaded image and return results for Gradio interface
72
+ """
73
+ if image is None:
74
+ return None, "No image uploaded"
 
 
 
 
 
 
 
75
 
76
  try:
77
+ # Process the image with the model
78
  start_time = time.time()
79
+ result_image, count_summary = count_fruits(image, conf=confidence)
80
+ processing_time = time.time() - start_time
81
 
82
+ # Add processing time to summary
83
+ full_summary = f"{count_summary}\n\nProcessing time: {processing_time:.2f} seconds"
84
 
85
+ return result_image, full_summary
86
+ except Exception as e:
87
+ logger.error(f"Error processing image: {str(e)}")
88
+ return None, f"Error: {str(e)}"
89
+
90
+ # Create Gradio interface
91
+ def create_interface():
92
+ with gr.Blocks(title="Fruit Detection") as demo:
93
+ gr.Markdown("# 🍎 Fruit Detection and Counting 🍌")
94
+ gr.Markdown("Upload an image to detect and count fruits")
95
 
96
+ with gr.Row():
97
+ with gr.Column():
98
+ input_image = gr.Image(type="numpy", label="Input Image")
99
+ confidence = gr.Slider(
100
+ minimum=0.1,
101
+ maximum=1.0,
102
+ value=0.25,
103
+ step=0.05,
104
+ label="Confidence Threshold"
105
+ )
106
+ submit_btn = gr.Button("Detect Fruits")
107
+
108
+ with gr.Column():
109
+ output_image = gr.Image(type="numpy", label="Detection Results")
110
+ output_text = gr.Textbox(label="Fruit Counts")
111
 
112
+ submit_btn.click(
113
+ fn=process_image,
114
+ inputs=[input_image, confidence],
115
+ outputs=[output_image, output_text]
116
+ )
117
 
118
+ gr.Markdown("## How to use")
119
+ gr.Markdown("1. Upload an image containing fruits")
120
+ gr.Markdown("2. Adjust the confidence threshold if needed")
121
+ gr.Markdown("3. Click 'Detect Fruits' to process the image")
122
+ gr.Markdown("4. View the detected fruits and counts")
 
 
 
 
 
 
 
123
 
124
+ if model is None:
125
+ gr.Warning("⚠️ Model failed to load. The application might not work correctly.")
126
+
127
+ return demo
128
 
129
+ # Launch the Gradio app
130
+ demo = create_interface()
 
 
131
 
132
+ if __name__ == "__main__":
133
+ # Gradio will use the default port for HF Spaces
134
+ demo.launch()