SakibAhmed commited on
Commit
decb0e0
·
verified ·
1 Parent(s): 0bcf8a3

Upload 3 files

Browse files
Files changed (3) hide show
  1. models/.env +5 -0
  2. models/app.py +153 -0
  3. models/models/best_TA_377EP.pt +3 -0
models/.env ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # Name of the first model (e.g., your original classifier)
2
+ MODEL_1_NAME=best_88E.pt
3
+
4
+ # Name of the second model (for Tyre/Alloy classification)
5
+ MODEL_2_NAME=best_TA_377EP.pt
models/app.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+
3
+ import os
4
+ import torch
5
+ from flask import Flask, request, jsonify, render_template
6
+ from flask_cors import CORS
7
+ from werkzeug.utils import secure_filename
8
+ from ultralytics import YOLO
9
+ from dotenv import load_dotenv
10
+
11
+ # Load environment variables from .env file
12
+ load_dotenv()
13
+
14
+ app = Flask(__name__)
15
+
16
+ # Enable CORS for all routes
17
+ CORS(app)
18
+
19
+ # --- Configuration ---
20
+ UPLOAD_FOLDER = 'static/uploads'
21
+ MODELS_FOLDER = 'models'
22
+ ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}
23
+
24
+ # --- NEW: Load model names from .env file, with fallback defaults ---
25
+ MODEL_1_NAME = os.getenv('MODEL_1_NAME', 'best.pt')
26
+ MODEL_2_NAME = os.getenv('MODEL_2_NAME', 'tyre_alloy.pt') # New model for Tyre/Alloy
27
+
28
+ MODEL_1_PATH = os.path.join(MODELS_FOLDER, MODEL_1_NAME)
29
+ MODEL_2_PATH = os.path.join(MODELS_FOLDER, MODEL_2_NAME)
30
+
31
+ app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
32
+ os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
33
+ os.makedirs(MODELS_FOLDER, exist_ok=True)
34
+ os.makedirs('templates', exist_ok=True)
35
+
36
+ # --- Determine Device ---
37
+ device = "cuda" if torch.cuda.is_available() else "cpu"
38
+ print(f"Using device: {device}")
39
+
40
+ # --- NEW: Load multiple YOLO Models ---
41
+ model1, model2 = None, None
42
+
43
+ # Load Model 1
44
+ try:
45
+ if not os.path.exists(MODEL_1_PATH):
46
+ print(f"Warning: Model file not found at {MODEL_1_PATH}")
47
+ else:
48
+ model1 = YOLO(MODEL_1_PATH)
49
+ model1.to(device)
50
+ print(f"Successfully loaded model '{MODEL_1_NAME}' on {device}.")
51
+ except Exception as e:
52
+ print(f"Error loading Model 1 ({MODEL_1_NAME}): {e}")
53
+
54
+ # Load Model 2
55
+ try:
56
+ if not os.path.exists(MODEL_2_PATH):
57
+ print(f"Warning: Model file not found at {MODEL_2_PATH}")
58
+ else:
59
+ model2 = YOLO(MODEL_2_PATH)
60
+ model2.to(device)
61
+ print(f"Successfully loaded model '{MODEL_2_NAME}' on {device}.")
62
+ except Exception as e:
63
+ print(f"Error loading Model 2 ({MODEL_2_NAME}): {e}")
64
+
65
+
66
+ def allowed_file(filename):
67
+ """Checks if a file's extension is in the ALLOWED_EXTENSIONS set."""
68
+ return '.' in filename and \
69
+ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
70
+
71
+ def run_inference(model, filepath):
72
+ """Helper function to run inference and format the result."""
73
+ if model is None:
74
+ return None # Return None if the model isn't loaded
75
+
76
+ results = model(filepath)
77
+ result = results[0]
78
+ probs = result.probs
79
+ top1_index = probs.top1
80
+ top1_confidence = float(probs.top1conf)
81
+ class_name = model.names[top1_index]
82
+
83
+ return {
84
+ "class": class_name,
85
+ "confidence": top1_confidence
86
+ }
87
+
88
+ @app.route('/')
89
+ def home():
90
+ """Serve the main HTML page."""
91
+ return render_template('index.html')
92
+
93
+ @app.route('/predict', methods=['POST'])
94
+ def predict():
95
+ """
96
+ Endpoint to receive an image and run classification based on the requested model type.
97
+ """
98
+ # 1. --- File Validation ---
99
+ if 'file' not in request.files:
100
+ return jsonify({"error": "No file part in the request"}), 400
101
+ file = request.files['file']
102
+ if file.filename == '':
103
+ return jsonify({"error": "No selected file"}), 400
104
+ if not file or not allowed_file(file.filename):
105
+ return jsonify({"error": "File type not allowed"}), 400
106
+
107
+ # --- NEW: Get the model type from the form data ---
108
+ model_type = request.form.get('model_type', 'model1') # default to model1
109
+
110
+ # 2. --- Save the File Temporarily ---
111
+ filename = secure_filename(file.filename)
112
+ filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
113
+ file.save(filepath)
114
+
115
+ # 3. --- Perform Inference based on model_type ---
116
+ try:
117
+ if model_type == 'model1':
118
+ if model1 is None:
119
+ return jsonify({"error": f"Model '{MODEL_1_NAME}' is not loaded. Check server logs."}), 500
120
+ prediction = run_inference(model1, filepath)
121
+ return jsonify(prediction)
122
+
123
+ elif model_type == 'model2':
124
+ if model2 is None:
125
+ return jsonify({"error": f"Model '{MODEL_2_NAME}' is not loaded. Check server logs."}), 500
126
+ prediction = run_inference(model2, filepath)
127
+ return jsonify(prediction)
128
+
129
+ elif model_type == 'combined':
130
+ if model1 is None or model2 is None:
131
+ return jsonify({"error": "One or more models required for combined mode are not loaded. Check server logs."}), 500
132
+
133
+ pred1 = run_inference(model1, filepath)
134
+ pred2 = run_inference(model2, filepath)
135
+
136
+ combined_prediction = {
137
+ "model1_result": pred1,
138
+ "model2_result": pred2
139
+ }
140
+ return jsonify(combined_prediction)
141
+
142
+ else:
143
+ return jsonify({"error": "Invalid model type specified"}), 400
144
+
145
+ except Exception as e:
146
+ return jsonify({"error": f"An error occurred during inference: {str(e)}"}), 500
147
+ finally:
148
+ # 4. --- Cleanup ---
149
+ if os.path.exists(filepath):
150
+ os.remove(filepath)
151
+
152
+ if __name__ == '__main__':
153
+ app.run(host='0.0.0.0', port=7860, debug=True)
models/models/best_TA_377EP.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0e36d1c8021842cf1b115648bc1ba02e62f43ca888effd7ef56d738f72c6328e
3
+ size 68680503