""" Flask Web Application for Multimodal Glaucoma Detection Provides web interface for Fundus, OCT, and Multimodal predictions """ from flask import Flask, render_template, request, jsonify, send_from_directory import os import sys # Ensure the project root is in sys.path sys.path.append(os.path.dirname(os.path.abspath(__file__))) from pathlib import Path import base64 from io import BytesIO from models.load_models import ModelLoader from models.predict import predict_fundus, predict_oct, predict_multimodal from utils.gradcam import generate_gradcam_image import traceback app = Flask(__name__) app.config['UPLOAD_FOLDER'] = 'static/uploads' app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max file size # Ensure upload directory exists os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) # Load models on startup print("Loading models...") model_loader = ModelLoader() print("Models loaded successfully!") @app.route('/') def index(): """Landing page with mode selection""" return render_template('index.html') @app.route('/fundus') def fundus_page(): """Fundus analysis page""" return render_template('upload.html', mode='fundus') @app.route('/oct') def oct_page(): """OCT analysis page""" return render_template('upload.html', mode='oct') @app.route('/multimodal') def multimodal_page(): """Multimodal analysis page""" return render_template('upload.html', mode='multimodal') @app.route('/about') def about_page(): """About page""" return render_template('about.html') @app.route('/predict/fundus', methods=['POST']) def predict_fundus_endpoint(): """Fundus prediction endpoint""" try: if 'fundus_image' not in request.files: return jsonify({'error': 'No fundus image provided'}), 400 file = request.files['fundus_image'] if file.filename == '': return jsonify({'error': 'No file selected'}), 400 # Save uploaded file filepath = os.path.join(app.config['UPLOAD_FOLDER'], 'fundus_temp.jpg') file.save(filepath) # Get prediction result = predict_fundus(filepath, model_loader) return jsonify(result) except Exception as e: print(f"Error in fundus prediction: {e}") traceback.print_exc() return jsonify({'error': str(e)}), 500 @app.route('/predict/oct', methods=['POST']) def predict_oct_endpoint(): """OCT prediction endpoint""" try: if 'oct_image' not in request.files: return jsonify({'error': 'No OCT image provided'}), 400 file = request.files['oct_image'] if file.filename == '': return jsonify({'error': 'No file selected'}), 400 # Save uploaded file filepath = os.path.join(app.config['UPLOAD_FOLDER'], 'oct_temp.jpg') file.save(filepath) # Get prediction result = predict_oct(filepath, model_loader) return jsonify(result) except Exception as e: print(f"Error in OCT prediction: {e}") traceback.print_exc() return jsonify({'error': str(e)}), 500 @app.route('/predict/multimodal', methods=['POST']) def predict_multimodal_endpoint(): """Multimodal prediction endpoint""" try: if 'fundus_image' not in request.files or 'oct_image' not in request.files: return jsonify({'error': 'Both fundus and OCT images required'}), 400 fundus_file = request.files['fundus_image'] oct_file = request.files['oct_image'] if fundus_file.filename == '' or oct_file.filename == '': return jsonify({'error': 'No file selected'}), 400 # Save uploaded files fundus_path = os.path.join(app.config['UPLOAD_FOLDER'], 'fundus_temp.jpg') oct_path = os.path.join(app.config['UPLOAD_FOLDER'], 'oct_temp.jpg') fundus_file.save(fundus_path) oct_file.save(oct_path) # Get prediction result = predict_multimodal(fundus_path, oct_path, model_loader) return jsonify(result) except Exception as e: print(f"Error in multimodal prediction: {e}") traceback.print_exc() return jsonify({'error': str(e)}), 500 if __name__ == '__main__': print("\n" + "="*60) print("Multimodal Glaucoma Detection System") print("="*60) print("Server starting on http://localhost:5000") print("Press Ctrl+C to stop") print("="*60 + "\n") app.run(debug=False, host='0.0.0.0', port=7860)