Spaces:
Sleeping
Sleeping
File size: 6,760 Bytes
9b81ce3 fa99c0b 9b81ce3 fa99c0b 9b81ce3 fa99c0b 9b81ce3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
import os
import cv2
import numpy as np
import pandas as pd
import base64
from flask import Flask, render_template, request, jsonify
from werkzeug.utils import secure_filename
from io import BytesIO
from PIL import Image
import tensorflow as tf
from tensorflow.keras.models import load_model
# Suppress warnings
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
os.environ['MPLCONFIGDIR'] = '/tmp/matplotlib'
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg'}
os.makedirs(app.config['UPLOAD_FOLDER'], mode=0o777, exist_ok=True)
# Load model
print("Loading traffic sign classification model...")
model = load_model('tabela_tespit.h5', compile=False)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
print("✓ Model loaded successfully!")
# Load labels
labels_df = pd.read_csv('labels.csv')
print(f"✓ Loaded {len(labels_df)} traffic sign classes")
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
def preprocess_image(image_path):
"""Preprocess image for CNN model (32x32 grayscale)"""
try:
# Read original image for display
img_original = cv2.imread(image_path)
if img_original is None:
raise ValueError("Could not read image")
# Convert to RGB for display
img_display = cv2.cvtColor(img_original, cv2.COLOR_BGR2RGB)
# Read as grayscale for model
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
print(f"Original image shape: {img.shape}")
# Resize to 32x32 for model
img_resized = cv2.resize(img, (32, 32))
# Apply histogram equalization
img_equalized = cv2.equalizeHist(img_resized)
# Normalize to [0, 1]
img_normalized = img_equalized / 255.0
# Add dimensions: (1, 32, 32, 1)
img_input = img_normalized.reshape(1, 32, 32, 1)
print(f"Model input shape: {img_input.shape}")
return img_input, img_display
except Exception as e:
raise ValueError(f"Failed to preprocess image: {str(e)}")
def img_to_base64(img):
"""Convert numpy image to base64 string"""
img_pil = Image.fromarray(img.astype('uint8'))
buf = BytesIO()
img_pil.save(buf, format='PNG')
buf.seek(0)
img_base64 = base64.b64encode(buf.getvalue()).decode('utf-8')
return f'data:image/png;base64,{img_base64}'
@app.route('/')
def index():
return render_template('index.html')
@app.route('/predict', methods=['POST'])
def predict():
try:
if 'file' not in request.files:
return jsonify({'error': 'No file uploaded'}), 400
file = request.files['file']
if file.filename == '':
return jsonify({'error': 'No file selected'}), 400
if not allowed_file(file.filename):
return jsonify({'error': 'Invalid file type. Please upload PNG, JPG, or JPEG'}), 400
# Save file
filename = secure_filename(file.filename)
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(filepath)
print(f"Processing: {filename}")
# Preprocess
img_input, img_display = preprocess_image(filepath)
# Predict
print("Making prediction...")
predictions = model.predict(img_input, verbose=0)
# Get top prediction
class_id = np.argmax(predictions)
confidence = np.max(predictions)
class_name = labels_df.loc[class_id, 'Name']
# Get top 5 predictions
top5_indices = np.argsort(predictions[0])[-5:][::-1]
top5_predictions = []
for idx in top5_indices:
top5_predictions.append({
'class_id': int(idx),
'class_name': labels_df.loc[idx, 'Name'],
'confidence': float(predictions[0][idx])
})
# Convert image to base64
img_base64 = img_to_base64(img_display)
# Clean up
os.remove(filepath)
result = {
'predicted_class': class_name,
'class_id': int(class_id),
'confidence': float(confidence),
'top5_predictions': top5_predictions,
'image': img_base64
}
print(f"✓ Prediction: {class_name} (Confidence: {confidence:.2%})")
return jsonify(result)
except Exception as e:
print(f"Error during prediction: {e}")
import traceback
traceback.print_exc()
if os.path.exists(filepath):
os.remove(filepath)
return jsonify({'error': str(e)}), 500
@app.route('/test-example', methods=['POST'])
def test_example():
"""Test with example image"""
try:
example_path = 'image.jpg'
if not os.path.exists(example_path):
return jsonify({'error': 'Example image not found'}), 404
print(f"Testing with example: {example_path}")
# Preprocess
img_input, img_display = preprocess_image(example_path)
# Predict
print("Making prediction on example...")
predictions = model.predict(img_input, verbose=0)
# Get top prediction
class_id = np.argmax(predictions)
confidence = np.max(predictions)
class_name = labels_df.loc[class_id, 'Name']
# Get top 5 predictions
top5_indices = np.argsort(predictions[0])[-5:][::-1]
top5_predictions = []
for idx in top5_indices:
top5_predictions.append({
'class_id': int(idx),
'class_name': labels_df.loc[idx, 'Name'],
'confidence': float(predictions[0][idx])
})
# Convert image to base64
img_base64 = img_to_base64(img_display)
result = {
'predicted_class': class_name,
'class_id': int(class_id),
'confidence': float(confidence),
'top5_predictions': top5_predictions,
'image': img_base64
}
print(f"✓ Example prediction: {class_name} (Confidence: {confidence:.2%})")
return jsonify(result)
except Exception as e:
print(f"Error during example prediction: {e}")
import traceback
traceback.print_exc()
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=False)
|