Spaces:
Sleeping
Sleeping
| from flask import Flask, request, render_template, redirect, url_for, session, send_file | |
| import cv2 | |
| import numpy as np | |
| import os | |
| import pickle | |
| import logging | |
| from werkzeug.utils import secure_filename | |
| from datetime import datetime | |
| from reportlab.lib.pagesizes import A4 | |
| from reportlab.pdfgen import canvas | |
| app = Flask(__name__) | |
| app.secret_key = os.getenv("FLASK_SECRET_KEY", "fallback_secret_key") | |
| # Set up logging | |
| app.logger.setLevel(logging.DEBUG) | |
| # Base directory (works when run from project root or Docker /app) | |
| BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| TEMP_DIR = os.path.join(BASE_DIR, 'temp') | |
| model_path = os.path.join(BASE_DIR, 'breast_cancer_detector.pickle') | |
| # Load trained cancer detection model | |
| cancer_detection_model = None | |
| try: | |
| if os.path.isfile(model_path): | |
| with open(model_path, 'rb') as model_file: | |
| cancer_detection_model = pickle.load(model_file) | |
| app.logger.info(f"Model loaded successfully from {model_path}") | |
| else: | |
| app.logger.warning(f"Model file not found at {model_path}. Run: python train_model.py") | |
| except Exception as e: | |
| app.logger.error(f"Error loading model: {e}") | |
| raise | |
| # Ensure the temp directory exists for saving uploaded images and PDFs | |
| if not os.path.exists(TEMP_DIR): | |
| os.makedirs(TEMP_DIR) | |
| def home(): | |
| return redirect(url_for('upload')) | |
| # Upload page | |
| def upload(): | |
| app.logger.debug('Upload page accessed') | |
| return render_template('upload.html') | |
| # Handle image upload and cancer detection | |
| def detect_cancer(): | |
| app.logger.debug('Detect Cancer page accessed') | |
| if request.method == 'POST': | |
| user_name = request.form.get('name', '').strip() | |
| session['user_name'] = user_name | |
| session['upload_date'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') | |
| # Get the uploaded image | |
| file = request.files.get('image') | |
| if file and allowed_file(file.filename): | |
| filename = secure_filename(file.filename) | |
| filepath = os.path.join(TEMP_DIR, filename) | |
| file.save(filepath) | |
| session['image_path'] = filepath | |
| if cancer_detection_model is None: | |
| return render_template('error.html', error_message="Model not loaded. Run train_model.py to create the model.") | |
| try: | |
| preprocessed_image = preprocess_image(filepath) | |
| prediction = cancer_detection_model.predict(preprocessed_image) | |
| result_message = 'Cancer Detected' if prediction[0] == 1 else 'No Cancer Detected' | |
| session['detection_result'] = result_message | |
| # Generate PDF report | |
| pdf_path = generate_pdf_report(user_name, session['upload_date'], filepath, result_message) | |
| session['pdf_path'] = pdf_path | |
| return redirect(url_for('show_result', result=result_message)) | |
| except Exception as e: | |
| app.logger.error(f"Error during prediction: {e}") | |
| return render_template('error.html', error_message="Error processing the image. Try again.") | |
| else: | |
| app.logger.warning('Invalid file type') | |
| return render_template('error.html', error_message="Invalid file type. Upload a valid image.") | |
| return redirect(url_for('upload')) | |
| # Display the result and provide PDF download link | |
| def show_result(): | |
| result = request.args.get('result', 'No result available') | |
| user_name = session.get('user_name', 'User') | |
| pdf_path = session.get('pdf_path') | |
| return render_template('result.html', result=result, user_name=user_name, pdf_path=pdf_path) | |
| # Download the PDF report | |
| def download_report(): | |
| pdf_path = session.get('pdf_path') | |
| if pdf_path and os.path.exists(pdf_path): | |
| session.clear() # Clear session after download | |
| return send_file(pdf_path, as_attachment=True) | |
| else: | |
| return "Report not found." | |
| # Preprocess the uploaded image | |
| def preprocess_image(image_path): | |
| try: | |
| image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) | |
| if image is None: | |
| raise ValueError("Could not read image file; file may be corrupt or not a valid image.") | |
| resized_image = cv2.resize(image, (5, 6)) | |
| flattened_image = resized_image.flatten() | |
| reshaped_image = flattened_image.reshape(1, -1) | |
| return reshaped_image | |
| except Exception as e: | |
| app.logger.error(f"Error in preprocessing image: {e}") | |
| raise | |
| # Generate PDF report | |
| def generate_pdf_report(user_name, upload_date, image_path, result): | |
| safe_name = "".join(c if c.isalnum() or c in "._- " else "_" for c in (user_name or "User")) | |
| pdf_name = f'report_{safe_name}_{datetime.now().strftime("%Y%m%d_%H%M%S")}.pdf' | |
| pdf_path = os.path.join(TEMP_DIR, pdf_name) | |
| c = canvas.Canvas(pdf_path, pagesize=A4) | |
| width, height = A4 | |
| # Add content to PDF | |
| c.drawString(50, height - 50, "Cancer Detection Report") | |
| c.drawString(50, height - 100, f"User Name: {user_name}") | |
| c.drawString(50, height - 120, f"Upload Date: {upload_date}") | |
| c.drawString(50, height - 140, f"Detection Result: {result}") | |
| c.drawString(50, height - 160, "Image Processing Details:") | |
| c.drawString(70, height - 180, "- Resized to 5x6 pixels") | |
| c.drawString(70, height - 200, "- Converted to grayscale") | |
| # Add recommendations if cancer is detected | |
| if result == "Cancer Detected": | |
| c.drawString(50, height - 240, "Recommendations:") | |
| c.drawString(70, height - 260, "- Consult a healthcare provider.") | |
| c.drawString(70, height - 280, "- Schedule additional diagnostic tests.") | |
| c.showPage() | |
| c.save() | |
| return pdf_path | |
| # Check if the uploaded file is an allowed image | |
| ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'} | |
| def allowed_file(filename): | |
| return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS | |
| # Custom Error Pages | |
| def page_not_found(error): | |
| return render_template('error.html', error_message="Page not found. Check the URL."), 404 | |
| def internal_server_error(error): | |
| return render_template('error.html', error_message="Unexpected error. Try again."), 500 | |