koesan's picture
Update app.py
fa99c0b verified
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)