from flask import Flask, flash, request, redirect, render_template import os import cv2 import imutils import numpy as np from tensorflow.keras.models import load_model from werkzeug.utils import secure_filename import tempfile from pymongo import MongoClient from datetime import datetime # Load the Brain Tumor CNN Model braintumor_model = load_model('models/braintumor_binary.h5') # Configuring Flask application app = Flask(__name__) app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 # Disable caching for images app.secret_key = "nielitchandigarhpunjabpolice" # Secret key for session management # Allowed image file extensions ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg']) # Connect to MongoDB Atlas client = MongoClient("mongodb+srv://test:test@cluster0.sxci1.mongodb.net/?retryWrites=true&w=majority") db = client['brain_tumor_detection'] # Database name collection = db['predictions'] # Collection name def allowed_file(filename): """Check if the file is a valid image format (png, jpg, jpeg).""" return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS def preprocess_imgs(set_name, img_size): """ Preprocess images by resizing them to the target size (224x224 for VGG16) and applying appropriate resizing techniques. """ set_new = [] for img in set_name: img = cv2.resize(img, dsize=img_size, interpolation=cv2.INTER_CUBIC) # Resize image set_new.append(img) return np.array(set_new) def crop_imgs(set_name, add_pixels_value=0): """ Crop the region of interest (ROI) in the image for brain tumor detection. """ set_new = [] for img in set_name: gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) gray = cv2.GaussianBlur(gray, (5, 5), 0) thresh = cv2.threshold(gray, 45, 255, cv2.THRESH_BINARY)[1] thresh = cv2.erode(thresh, None, iterations=2) thresh = cv2.dilate(thresh, None, iterations=2) cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) c = max(cnts, key=cv2.contourArea) extLeft = tuple(c[c[:, :, 0].argmin()][0]) extRight = tuple(c[c[:, :, 0].argmax()][0]) extTop = tuple(c[c[:, :, 1].argmin()][0]) extBot = tuple(c[c[:, :, 1].argmax()][0]) ADD_PIXELS = add_pixels_value new_img = img[extTop[1]-ADD_PIXELS:extBot[1]+ADD_PIXELS, extLeft[0]-ADD_PIXELS:extRight[0]+ADD_PIXELS].copy() set_new.append(new_img) return np.array(set_new) @app.route('/') def brain_tumor(): """Render the HTML form for the user to upload an image.""" return render_template('braintumor.html') @app.route('/resultbt', methods=['POST']) def resultbt(): """Process the uploaded image and save prediction results to MongoDB.""" if request.method == 'POST': firstname = request.form['firstname'] lastname = request.form['lastname'] email = request.form['email'] phone = request.form['phone'] gender = request.form['gender'] age = request.form['age'] file = request.files['file'] if file and allowed_file(file.filename): temp_file = tempfile.NamedTemporaryFile(delete=False) filename = secure_filename(file.filename) file.save(temp_file.name) flash('Image successfully uploaded and displayed below') try: # Process the image img = cv2.imread(temp_file.name) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Convert to RGB img = crop_imgs([img]) img = img.reshape(img.shape[1:]) img = preprocess_imgs([img], (128, 128)) # Match model's input size img = np.expand_dims(img, axis=0) # Add batch dimension # Make prediction pred = braintumor_model.predict(img) prediction = 'Tumor Detected' if pred[0][0] >= 0.5 else 'No Tumor Detected' confidence_score = float(pred[0][0]) # Prepare data for MongoDB result = { "firstname": firstname, "lastname": lastname, "email": email, "phone": phone, "gender": gender, "age": age, "image_name": filename, "prediction": prediction, "confidence_score": confidence_score, "timestamp": datetime.utcnow() } # Insert data into MongoDB collection.insert_one(result) # Return the result to the user return render_template('resultbt.html', filename=filename, fn=firstname, ln=lastname, age=age, r=prediction, gender=gender) finally: os.remove(temp_file.name) # Ensure temporary file is deleted else: flash('Allowed image types are - png, jpg, jpeg') return redirect(request.url) @app.route('/dbresults') def dbresults(): """Fetch all results from MongoDB, show aggregated data, and render in a template.""" # Fetch all documents from MongoDB, sorted by timestamp in descending order all_results = collection.find().sort("timestamp", -1) # Sort by timestamp, latest first # Convert cursor to a list of dictionaries results_list = [] tumor_count = 0 no_tumor_count = 0 for result in all_results: result['_id'] = str(result['_id']) # Convert ObjectId to string for JSON serialization results_list.append(result) # Count total patients with tumor and without tumor if result['prediction'] == 'Tumor Detected': tumor_count += 1 else: no_tumor_count += 1 total_patients = len(results_list) # Total number of patients # Pass the results and aggregated counts to the HTML template return render_template('dbresults.html', results=results_list, total_patients=total_patients, tumor_count=tumor_count, no_tumor_count=no_tumor_count) if __name__ == '__main__': app.run(debug=True)