top of page

Building a Brain Tumor Prediction Web Application Using Django


In this tutorial, we will walk you through creating a brain tumor prediction web application using Django, a popular web framework for Python. This project will allow users to upload an MRI image and receive a prediction on whether the brain tumor is present, as well as what type of tumor it is, using a pre-trained machine learning model. We will explain each step in detail, so even beginner-level students can follow along.


Prerequisites

Before we start, make sure you have the following tools installed:

  • Python 3.x: You can download Python from the official site here.

  • Django: We will use Django to build our web application.


Project Overview

We will divide the project into several stages:

  1. Set up a Django project and virtual environment.

  2. Create the necessary Django app for brain tumor detection.

  3. Build forms to upload images.

  4. Integrate a machine learning model to make predictions.

  5. Display the prediction results to the user.


Step 1: Setting Up the Django Project

  1. Create a directory for your project and navigate to it using the terminal.

mkdir brain_tumor_prediction
cd brain_tumor_prediction

Create a virtual environment using the following command:

python -m venv env

Activate the virtual environment:

  • On Windows:

env\Scripts\activate

On macOS/Linux:

source env/bin/activate

Install Django within the virtual environment:

pip install django

Create a new Django project:

django-admin startproject brain_tumor

Navigate into the project directory:

cd brain_tumor

Run the Django development server:

python manage.py runserver

If everything is set up correctly, you should see the default Django welcome page in your browser at http://127.0.0.1:8000/.


Step 2: Create the Brain Tumor Detection App

  1. Create a Django app within your project:

python manage.py startapp brain_tumor_detection

Add the new app to your Django project's INSTALLED_APPS in the settings.py file:

INSTALLED_APPS = [
    # other default apps
    'brain_tumor_detection',
]

Step 3: Setting Up the Folder Structure and Files

In the brain_tumor project folder, your structure will look like this:

brain_tumor/
│
├── brain_tumor/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
│   ├── asgi.py
│   └── ...
│
├── brain_tumor_detection/
│   ├── migrations/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── forms.py
│   ├── views.py
│   ├── urls.py
│   └── templates/
│       ├── upload_image.html
│       └── prediction_result.html
│
├── db.sqlite3
├── manage.py
└── ...

Code for apps.py

We will create a model for storing the uploaded images and their corresponding predictions.

from django.apps import AppConfig


class BrainTumorDetectionConfig(AppConfig):
    default_auto_field = "django.db.models.BigAutoField"
    name = "brain_tumor_detection"

Code for forms.py

Here, we will create a form to handle image uploads.

from django import forms

class ImageUploadForm(forms.Form):
    image_file = forms.ImageField(
        label='Upload Image',
        widget=forms.ClearableFileInput(attrs={'class': 'upload-input'}),
    )

Step 4: Setting Up URLs

We need to define URL patterns to handle the image upload and display the prediction result.


Code for urls.py in the brain_tumor_detection folder:

from django.urls import path
from .views import upload_image, prediction_result

app_name = 'brain_tumor_detection'
 

urlpatterns = [
    path('', upload_image, name='upload_image'),
    path('prediction/<int:image_id>/', prediction_result, name='prediction_result'),
]

In the main brain_tumor/urls.py, include the app's URLs:

from django.contrib import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path("admin/", admin.site.urls),
    path('', include('brain_tumor_detection.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Step 5: Setting Up Views

We will now handle the logic for processing image uploads and making predictions using a pre-trained model.


Code for views.py:

from django.shortcuts import render, redirect
from .forms import ImageUploadForm
from .models import Image
import tensorflow as tf
import numpy as np
from PIL import Image as PilImage
import io

# Load your trained model
model = tf.keras.models.load_model('./brain_tumor_detection/best_model.h5')

# Define a function for image prediction
def predict_image(image):
    # Preprocess the image if necessary (e.g., resize, normalize, etc.)
    image = image.resize((150, 150))  # Resize the image to match your model input shape
    image = np.array(image) / 255.0  # Normalize pixel values between 0 and 1

    # Expand dimensions to create a batch of size 1
    image = np.expand_dims(image, axis=0)

    if image.shape[-1] != 3:
        image = image[:,:,:,:3]

    # Perform prediction
    prediction = model.predict(image)

    # Get the predicted class index
    predicted_class_index = np.argmax(prediction)

    # Define your class labels
    class_labels = ['Sorry you have Glioma Tumor', 
                    'Sorry you have Meningioma Tumor', 
                    'Hey! you do not have any Tumor', 
                    'Sorry you have Pituitary Tumor']

    # Get the predicted class label
    predicted_class_label = class_labels[predicted_class_index]

    return predicted_class_label


def prediction_result(image_id):
    image = Image.objects.get(id=image_id)

    context = {'image': image}
    return context


def upload_image(request):
    if request.method == 'POST':
        form = ImageUploadForm(request.POST, request.FILES)
        if form.is_valid():
            image_file = form.cleaned_data['image_file']

            # Create a PIL Image object from the uploaded file
            pil_image = PilImage.open(image_file)

            # Perform prediction on the image
            prediction = predict_image(pil_image)

            # Create a new Image instance and save the prediction
            image = Image(image_file=image_file, prediction=prediction)
            image.save()
            context = prediction_result(image.id)
            
            return render(request, 'prediction_result.html', context)
    else:
        form = ImageUploadForm()

    context = {'form': form}
    return render(request, 'upload_image.html', context)

Step 6: Creating HTML Templates

We'll now create the front-end for our app to allow users to upload images and view predictions.

upload_image.html

This page allows users to upload an image.

<!DOCTYPE html>
<html>
<head>
  <title>Brain Tumor Detection</title>
  <style>
    body {
      font-family: Arial, sans-serif;
    }
    
    .container {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 90%;
    }

    .heading-container {
        background-color: skyblue;
        display: flex;
        align-items: top;
        justify-content: center;
        height: 10%;
        width: 30%;
        margin-left: 35%;
        border-radius: 10px;
    }
    
    
    .left-panel {
        background-color: lightslategray;
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 5%;
        margin: 5%;
        border-radius: 10px;
    }
    
    .right-panel {
      background-color: white;
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 5%;
      padding: 2%;
    }
    
    #image-preview {
      max-width: 400px;
      max-height: 400px;
    }
    
    .button {
      margin-bottom: 10px;
      padding: 10px 20px;
      border-radius: 5px;
      background-color: #4CAF50;
      color: white;
      font-size: 16px;
      text-align: center;
      cursor: pointer;
    }
    
    .button:hover {
      background-color: #45a049;
    }
    
    .hidden {
      display: none;
    }
  </style>
</head>
<body>
    <div class="heading-container">
        <h1>
            Brain Tumor Detection
        </h1>
    </div>
    <div class="container">
      <div class="left-panel">
        <h2>Choose/ Upload Image</h2>
        <form id="upload-form" method="post" enctype="multipart/form-data" action="">
          {% csrf_token %}
          <input type="file" id="image-upload" name="image_file" class="hidden">
          <label for="image-upload" class="button">Choose Image</label>
          <button type="submit" id="predict-button" class="button" disabled>Predict</button>
        </form>
      </div>
      <div class="right-panel">
        <img id="image-preview" src="#" alt="Preview" class="hidden">
      </div>
    </div>
  
    <script>
      const imageUpload = document.getElementById('image-upload');
      const predictButton = document.getElementById('predict-button');
      const imagePreview = document.getElementById('image-preview');
      const uploadForm = document.getElementById('upload-form');
  
      imageUpload.addEventListener('change', function(e) {
        const file = e.target.files[0];
        if (file) {
          const reader = new FileReader();
          reader.onload = function() {
            imagePreview.src = reader.result;
            imagePreview.classList.remove('hidden');
            predictButton.disabled = false;
          }
          reader.readAsDataURL(file);
        }
      });
    </script>
  </body>
  </html>

prediction_result.html

This page shows the prediction result after the image has been uploaded.

<!DOCTYPE html>
<html>
<head>
    <title>Prediction Result</title>
    <style>
        body {
    font-family: Arial, sans-serif;
    color: #fff;
    margin: 2;
    padding: 0;
    min-height: 100vh;
}

        h1 {
            text-align: center;
            margin-bottom: 30px;
        }

        .prediction-card {
            width: 400px;
            margin: 0 auto;
            background: linear-gradient(to bottom right, #3498db, #2c3e50);;
            border-radius: 5px;
            padding: 20px;
            text-align: center;
        }

        .prediction-card h2 {
            margin-top: 0;
        }

        .prediction-card p {
            margin-bottom: 20px;
        }

        .back-button {
            display: block;
            width: 100px;
            margin: 20px auto;
            background-color: #3498db;
            color: #fff;
            padding: 10px 20px;
            text-decoration: none;
            text-align: center;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <h1>Prediction Result</h1>
    <div class="prediction-card">
        <h2 style="color: black;">Prediction:</h2>
        <p style="color: black;">{{ image.prediction }}</p>
        <img src="{{ MEDIA_URL }}{{ image.image_file.url }}" alt="Uploaded Image" width="200">
    </div>
</body>
</html>

Step 7: Setting Up Static and Media Files

In your settings.py, add the following to handle media files:

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

This allows Django to serve the uploaded images properly.


Step 8: Running Migrations

Before running the application, apply migrations to set up the database:

python manage.py migrate

Step 9: Testing the Application

  1. Start the server:

python manage.py runserver
  1. Open http://127.0.0.1:8000/ in your browser. You should see the image upload form.

  2. After uploading an MRI image, the prediction result will be displayed on the results page.


Project Demo Video




You can see we have successfully built a brain tumor prediction web application using Django. This tutorial covers how to create the basic app structure, set up forms, and integrate a machine learning model for image classification. You can now expand this project by adding more features, such as user authentication, more advanced image processing, or even deploying the app to a cloud platform.


If you require any assistance with this project or Machine Learning projects, please do not hesitate to contact us. We have a team of experienced developers who specialize in Machine Learning and can provide you with the necessary support and expertise to ensure the success of your project. You can reach us through our website or by contacting us directly via email or phone.



Opmerkingen


bottom of page