Spaces:
Running
Running
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:[email protected]/?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) | |
def brain_tumor(): | |
"""Render the HTML form for the user to upload an image.""" | |
return render_template('braintumor.html') | |
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) | |
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) |