koesan's picture
Update app.py
fa99c0b verified
Raw
History Blame Contribute Delete
6.76 kB
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)