diff --git a/.gitignore b/.gitignore
index 12a9eb27814870fb520e00cd9545e3dbf29385f1..5d4be9669829e68e2cfaba33d69614fde9d6703a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,9 @@ __pycache__/
 migrations/
 
 /media/
-media/
\ No newline at end of file
+media/
+
+
+uploads/
+
+/uploads/
\ No newline at end of file
diff --git a/MisplaceAI/Dockerfile b/MisplaceAI/Dockerfile
index 75bc76080b6ed65c800b45f3a8ea52e4cf3681a3..665e631d7a2dd5f37e71a8cb91de417f50fa61c9 100644
--- a/MisplaceAI/Dockerfile
+++ b/MisplaceAI/Dockerfile
@@ -34,8 +34,8 @@ ENV PYTHONPATH=$PYTHONPATH:/app/models:/app/models/research:/app/models/research
 # Create the media directory
 RUN mkdir -p /app/media
 
-# Expose port 8000 for the Django app
-EXPOSE 8000
+# Expose port 8080 for the Django app
+EXPOSE 8080
 
 # Run the Django server
-CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
+CMD ["python", "manage.py", "runserver", "0.0.0.0:8080"]
diff --git a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc
index 35c5da5b4fd5d421b404460cb3cdf37b3220e3ae..9bb104919fd41b0c254cad8c4525ffa468b51048 100644
Binary files a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc and b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc differ
diff --git a/MisplaceAI/MisplaceAI/settings.py b/MisplaceAI/MisplaceAI/settings.py
index b6afaac3a371d2098d1d467f9e1b9055a0a14a52..7696ee18f50cedeb35813f64bdf0b0009d42f59f 100644
--- a/MisplaceAI/MisplaceAI/settings.py
+++ b/MisplaceAI/MisplaceAI/settings.py
@@ -34,8 +34,9 @@ DEBUG = True
 
 
 
-ALLOWED_HOSTS = []
-
+# ALLOWED_HOSTS = []
+ 
+ALLOWED_HOSTS = ['*']  # This allows all hosts. Use with caution.
 
 
 # Application definition
@@ -153,3 +154,11 @@ STATICFILES_DIRS = [
 
 DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
 
+if DEBUG:
+    import requests
+    try:
+        ngrok_tunnel = requests.get('http://localhost:4040/api/tunnels').json()['tunnels'][0]['public_url']
+        ngrok_hostname = ngrok_tunnel.split("//")[-1].split(":")[0]
+        ALLOWED_HOSTS.append(ngrok_hostname)
+    except requests.exceptions.RequestException:
+        pass
\ No newline at end of file
diff --git a/MisplaceAI/core/templates/core/navbar.html b/MisplaceAI/core/templates/core/navbar.html
index 12bd44095a198ba9c70df720d713364abe5838a4..ab74aceedb7b86bc3d3c7ac108b0aa3a3958c74c 100644
--- a/MisplaceAI/core/templates/core/navbar.html
+++ b/MisplaceAI/core/templates/core/navbar.html
@@ -11,7 +11,8 @@
             </li>
             <!-- Add link to the image upload page -->
             <li class="nav-item">
-                <a class="nav-link" href="{% url 'process_misplaced_manager:upload_image' %}">Upload Image</a>
+                <a class="nav-link" href="{% url 'process_misplaced_manager:detection_options' %}">Detect Misplaced
+                    Items</a>
             </li>
             {% if user.is_authenticated %}
             {% if user.is_staff %}
diff --git a/MisplaceAI/docker-compose.yml b/MisplaceAI/docker-compose.yml
index 14ed08a921be340552864a1188b5310d59f5adc0..ef1b375fc20ad96f2f42270e3bc26352fded32e4 100644
--- a/MisplaceAI/docker-compose.yml
+++ b/MisplaceAI/docker-compose.yml
@@ -1,17 +1,21 @@
-#docker-compose.yml
 version: '3.7'
 
 services:
   web:
     build: .
-    command: python manage.py runserver 0.0.0.0:8000
+    command: python manage.py runserver 0.0.0.0:8080
     volumes:
       - .:/app
       - ./media:/app/media
     ports:
-      - "8000:8000"
+      - "8080:8080"
     depends_on:
       - db
+    healthcheck:
+      test: [ "CMD-SHELL", "curl -f http://localhost:8080/ || exit 1" ]
+      interval: 30s
+      timeout: 10s
+      retries: 5
 
   db:
     image: mysql:5.7
@@ -23,5 +27,17 @@ services:
     volumes:
       - mysql_data:/var/lib/mysql
 
+  ngrok:
+    image: wernight/ngrok
+    volumes:
+      - ./ngrok.yml:/home/ngrok/.ngrok2/ngrok.yml
+    command: ngrok start --all
+    depends_on:
+      web:
+        condition: service_healthy
+    ports:
+      - "4040:4040" # Expose Ngrok's web interface
+      - "8080" # Forward the port Django is running on through Ngrok
+
 volumes:
   mysql_data:
diff --git a/MisplaceAI/docs/webAPI.md b/MisplaceAI/docs/webAPI.md
new file mode 100644
index 0000000000000000000000000000000000000000..204e4251f756e063c5fab1ba23343fb4f805991b
--- /dev/null
+++ b/MisplaceAI/docs/webAPI.md
@@ -0,0 +1,31 @@
+## Adding ngrok URL to Django ALLOWED_HOSTS
+
+### Overview
+When using ngrok to tunnel your local Django server, you may encounter an Invalid HTTP_HOST header error. This happens because Django’s `ALLOWED_HOSTS` setting does not include the ngrok URL. To resolve this issue, you need to add the ngrok URL to the `ALLOWED_HOSTS` setting in your Django project’s `settings.py` file.
+
+### Steps to Fix the Issue
+1. **Locate Your Django Settings File**
+   First, locate your Django settings file. This file is typically named `settings.py` and can be found in your project directory. For example, it might be located at:
+
+<your_project>/<your_project>/settings.py
+
+### 2. Edit the ALLOWED_HOSTS Setting
+   Open the `settings.py` file in your preferred text editor or IDE. Find the `ALLOWED_HOSTS` setting and add your ngrok URL to the list. If the `ALLOWED_HOSTS` list is currently empty or not defined, it will look something like this:
+
+
+```bash
+ALLOWED_HOSTS = [
+    'localhost',
+    '127.0.0.1',
+    'f382-164-11-203-57.ngrok-free.app',  # Add your ngrok URL here
+]
+```
+
+### 3. Alternative Development Setting (Use with Caution)
+For development purposes, you can allow all hosts by using a wildcard `*`. However, this is not recommended for production environments due to security risks:
+
+```bash
+
+ALLOWED_HOSTS = ['*']  # This allows all hosts. Use with caution.
+
+```
diff --git a/MisplaceAI/ngrok.yml b/MisplaceAI/ngrok.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6ae991e53dbb531ea07d9544e72e4b6cd4773617
--- /dev/null
+++ b/MisplaceAI/ngrok.yml
@@ -0,0 +1,6 @@
+version: "2"
+authtoken: 2gjASz2oymOKoIZiuEWvPHog4MB_4q4if5LATt17Vc1hbsvnC
+tunnels:
+  django:
+    proto: http
+    addr: web:8080 # Use the service name defined in docker-compose.yml
diff --git a/MisplaceAI/process_misplaced_manager/forms.py b/MisplaceAI/process_misplaced_manager/forms.py
index fa7edd5c2e61e3302d2667a786bde1b0f51b0aa0..47b2ce438ef5a2e9971c55e393a9805f941f6514 100644
--- a/MisplaceAI/process_misplaced_manager/forms.py
+++ b/MisplaceAI/process_misplaced_manager/forms.py
@@ -1,7 +1,12 @@
 from django import forms
-from .models import UploadedImage
+from .models import UploadedImage, UploadedVideo
 
 class ImageUploadForm(forms.ModelForm):
     class Meta:
         model = UploadedImage
         fields = ['image']
+
+class VideoUploadForm(forms.ModelForm):
+    class Meta:
+        model = UploadedVideo
+        fields = ['video']
diff --git a/MisplaceAI/process_misplaced_manager/models.py b/MisplaceAI/process_misplaced_manager/models.py
index 1d73a62583f25455d02930af8b3a7a2470581e90..1a4537810b537322a3a9c1b1a6a5888460813f5a 100644
--- a/MisplaceAI/process_misplaced_manager/models.py
+++ b/MisplaceAI/process_misplaced_manager/models.py
@@ -1,8 +1,9 @@
 from django.db import models
 
 class UploadedImage(models.Model):
-    image = models.ImageField(upload_to='uploads/')
+    image = models.ImageField(upload_to='images/')
     uploaded_at = models.DateTimeField(auto_now_add=True)
 
-    def __str__(self):
-        return f"Image {self.id} uploaded at {self.uploaded_at}"
+class UploadedVideo(models.Model):
+    video = models.FileField(upload_to='videos/')
+    uploaded_at = models.DateTimeField(auto_now_add=True)
diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/detection_options.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/detection_options.html
new file mode 100644
index 0000000000000000000000000000000000000000..ff86beac9ae6d250458747248b268179283c5d78
--- /dev/null
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/detection_options.html
@@ -0,0 +1,20 @@
+{% extends 'core/base.html' %}
+
+{% block content %}
+<h1>Select Detection Method</h1>
+<div>
+    <a href="{% url 'process_misplaced_manager:normal_detection' %}">
+        <button>Misplaced Items using Normal Object Detection</button>
+    </a>
+</div>
+<div>
+    <a href="{% url 'process_misplaced_manager:segmentation_detection' %}">
+        <button>Misplaced Items using Segmentation</button>
+    </a>
+</div>
+<div>
+    <a href="{% url 'process_misplaced_manager:upload_video' %}">
+        <button>Misplaced Items using Video Detection</button>
+    </a>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_results.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_results.html
index 0ddd16070dfadb4a17688609ef603bd224667906..8a842a76b773319f10f0594253de5432e85f0089 100644
--- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_results.html
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_results.html
@@ -6,8 +6,8 @@
 <h2>Misplaced Objects</h2>
 <ul>
     {% for obj in misplaced_objects %}
-    <li>{{ obj.class_name }} is misplaced. Allowed locations: {{ obj.allowed_locations }}</li>
+    <li>{{ obj.class_name }} is misplaced. Allowed locations: {{ obj.allowed_locations|join:", " }}</li>
     {% endfor %}
 </ul>
-<a href="{% url 'process_misplaced_manager:upload_image' %}">Upload another image</a>
+<a href="{% url 'process_misplaced_manager:detection_options' %}">Try another detection</a>
 {% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/normal_detection.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/normal_detection.html
new file mode 100644
index 0000000000000000000000000000000000000000..b388c1c77a40f6f0ada620896ad5d8aed6ece31f
--- /dev/null
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/normal_detection.html
@@ -0,0 +1,88 @@
+{% extends 'core/base.html' %}
+
+{% block content %}
+<h1>Upload Image for Normal Detection</h1>
+<!-- Include WebcamJS library -->
+<script src="https://cdnjs.cloudflare.com/ajax/libs/webcamjs/1.0.26/webcam.min.js"></script>
+
+<form method="post" enctype="multipart/form-data" id="uploadForm">
+    {% csrf_token %}
+    <label for="id_image">Image:</label>
+    <input type="file" id="id_image" name="image" accept="image/*">
+    <button type="submit">Upload</button>
+</form>
+
+<!-- Button to open the camera interface -->
+<button id="openCameraBtn">Capture Image from Camera</button>
+
+<!-- Container for the camera feed -->
+<div id="camera" style="display: none;"></div>
+<!-- Container for the captured image -->
+<div id="capturedImage" style="display: none;">
+    <img id="imagePreview" src="" alt="Captured Image">
+    <input type="hidden" id="capturedImageData" name="capturedImageData">
+</div>
+
+<a href="{% url 'process_misplaced_manager:detection_options' %}">Back to Detection Options</a>
+
+<script>
+    document.getElementById('openCameraBtn').addEventListener('click', function () {
+        // Show the camera interface
+        document.getElementById('camera').style.display = 'block';
+
+        // Configure and attach the camera
+        Webcam.set({
+            width: 320,
+            height: 240,
+            image_format: 'jpeg',
+            jpeg_quality: 90
+        });
+        Webcam.attach('#camera');
+
+        // Capture the image
+        Webcam.snap(function (data_uri) {
+            // Show the captured image
+            document.getElementById('capturedImage').style.display = 'block';
+            document.getElementById('imagePreview').src = data_uri;
+
+            // Save the captured image data to the hidden input field
+            document.getElementById('capturedImageData').value = data_uri;
+
+            // Hide the camera interface
+            Webcam.reset();
+            document.getElementById('camera').style.display = 'none';
+        });
+    });
+
+    document.getElementById('uploadForm').addEventListener('submit', function (event) {
+        // If an image is captured from the camera, prevent the default form submission
+        const capturedImageData = document.getElementById('capturedImageData').value;
+        if (capturedImageData) {
+            event.preventDefault();
+
+            // Create a FormData object
+            const formData = new FormData();
+
+            // Append the CSRF token
+            formData.append('csrfmiddlewaretoken', '{{ csrf_token }}');
+
+            // Append the captured image data
+            formData.append('capturedImageData', capturedImageData);
+
+            // Send the form data via AJAX
+            fetch('{% url "process_misplaced_manager:normal_detection" %}', {
+                method: 'POST',
+                body: formData,
+            })
+                .then(response => response.json())
+                .then(data => {
+                    // Handle the response (e.g., redirect to the results page)
+                    window.location.href = data.redirect_url;
+                })
+                .catch(error => {
+                    console.error('Error:', error);
+                });
+        }
+    });
+</script>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/segmentation_detection.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/segmentation_detection.html
new file mode 100644
index 0000000000000000000000000000000000000000..892e93b633cfab9cd627cb583eb5fd2b94dc9a68
--- /dev/null
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/segmentation_detection.html
@@ -0,0 +1,12 @@
+{% extends 'core/base.html' %}
+
+{% block content %}
+<h1>Upload Image for Segmentation Detection</h1>
+<form method="post" enctype="multipart/form-data">
+    {% csrf_token %}
+    <label for="id_image">Image:</label>
+    <input type="file" name="image" accept="image/*" capture="camera" required>
+    <button type="submit">Upload</button>
+</form>
+<a href="{% url 'process_misplaced_manager:detection_options' %}">Back to Detection Options</a>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_image.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_image.html
index 7de40c0ff8da259433f2f03dfbc89a98ff3eb31e..0451cc3677170ef4a2485f59661d25c1e58ffa42 100644
--- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_image.html
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_image.html
@@ -7,4 +7,5 @@
     {{ form.as_p }}
     <button type="submit">Upload</button>
 </form>
+<a href="{% url 'process_misplaced_manager:detection_options' %}">Back to Detection Options</a>
 {% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_video.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_video.html
new file mode 100644
index 0000000000000000000000000000000000000000..f5fe13ce98fee50b4053b806d4112da4fd6a1344
--- /dev/null
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_video.html
@@ -0,0 +1,12 @@
+{% extends 'core/base.html' %}
+
+{% block content %}
+<h1>Upload Video for Detection</h1>
+<form method="post" enctype="multipart/form-data">
+    {% csrf_token %}
+    <label for="id_video">Video:</label>
+    <input type="file" name="video" accept="video/*" capture="camcorder" required>
+    <button type="submit">Upload</button>
+</form>
+<a href="{% url 'process_misplaced_manager:detection_options' %}">Back to Detection Options</a>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/process_misplaced_manager/urls.py b/MisplaceAI/process_misplaced_manager/urls.py
index d8e6e973a6319274b60d5d28f171c538fab5d43e..1b521fd654254949776dbe3a97e3e15f9c9ca73c 100644
--- a/MisplaceAI/process_misplaced_manager/urls.py
+++ b/MisplaceAI/process_misplaced_manager/urls.py
@@ -1,9 +1,13 @@
 from django.urls import path
-from .views import upload_image, display_results
+from . import views
 
 app_name = 'process_misplaced_manager'
 
 urlpatterns = [
-    path('upload/', upload_image, name='upload_image'),
-    path('results/<int:image_id>/', display_results, name='display_results'),
+    path('detection-options/', views.detection_options, name='detection_options'),
+    path('normal-detection/', views.normal_detection, name='normal_detection'),
+    path('segmentation-detection/', views.segmentation_detection, name='segmentation_detection'),
+    path('upload-video/', views.upload_video, name='upload_video'),
+    path('results/<int:image_id>/', views.display_results, name='display_results'),
+    path('video-results/<int:video_id>/', views.display_video_results, name='display_video_results'),
 ]
diff --git a/MisplaceAI/process_misplaced_manager/views.py b/MisplaceAI/process_misplaced_manager/views.py
index 356319757c5f42f31c00e53a6e9514f0a9f6494a..9634b564e23bd5cdb4582c2697d4eb57a95de20b 100644
--- a/MisplaceAI/process_misplaced_manager/views.py
+++ b/MisplaceAI/process_misplaced_manager/views.py
@@ -1,11 +1,13 @@
 from django.shortcuts import render, redirect, get_object_or_404
-from .forms import ImageUploadForm
-from .models import UploadedImage
+from .forms import ImageUploadForm, VideoUploadForm
+from .models import UploadedImage, UploadedVideo
 from item_detector.utils import run_inference, load_model, create_category_index_from_labelmap
 from placement_rules.utils import PlacementRules
 from results_viewer.utils import visualize_misplaced_objects
+import base64
 
 import os
+from django.core.files.base import ContentFile
 
 # Load the model and category index for object detection
 MODEL_PATH = "models/research/object_detection/faster_rcnn_resnet50_v1_1024x1024_coco17_tpu-8/saved_model"
@@ -14,7 +16,38 @@ LABEL_MAP_PATH = "models/research/object_detection/data/mscoco_label_map.pbtxt"
 detection_model = load_model(MODEL_PATH)
 category_index = create_category_index_from_labelmap(LABEL_MAP_PATH)
 
-def upload_image(request):
+def detection_options(request):
+    return render(request, 'process_misplaced_manager/detection_options.html')
+
+
+def normal_detection(request):
+    if request.method == 'POST':
+        if 'capturedImageData' in request.POST:
+            captured_image_data = request.POST['capturedImageData']
+            format, imgstr = captured_image_data.split(';base64,') 
+            ext = format.split('/')[-1] 
+            image_data = ContentFile(base64.b64decode(imgstr), name='temp.' + ext)
+
+            # Save the image to the UploadedImage model
+            new_image = UploadedImage.objects.create(image=image_data)
+            return redirect('process_misplaced_manager:display_results', image_id=new_image.id)
+        else:
+            form = ImageUploadForm(request.POST, request.FILES)
+            if form.is_valid():
+                new_image = form.save()
+                return redirect('process_misplaced_manager:display_results', image_id=new_image.id)
+    else:
+        form = ImageUploadForm()
+    return render(request, 'process_misplaced_manager/normal_detection.html', {'form': form})
+
+
+
+
+
+
+
+
+def segmentation_detection(request):
     if request.method == 'POST':
         form = ImageUploadForm(request.POST, request.FILES)
         if form.is_valid():
@@ -22,7 +55,17 @@ def upload_image(request):
             return redirect('process_misplaced_manager:display_results', image_id=new_image.id)
     else:
         form = ImageUploadForm()
-    return render(request, 'process_misplaced_manager/upload_image.html', {'form': form})
+    return render(request, 'process_misplaced_manager/segmentation_detection.html', {'form': form})
+
+def upload_video(request):
+    if request.method == 'POST':
+        form = VideoUploadForm(request.POST, request.FILES)
+        if form.is_valid():
+            new_video = form.save()
+            return redirect('process_misplaced_manager:display_video_results', video_id=new_video.id)
+    else:
+        form = VideoUploadForm()
+    return render(request, 'process_misplaced_manager/upload_video.html', {'form': form})
 
 def display_results(request, image_id):
     image = get_object_or_404(UploadedImage, id=image_id)
@@ -45,3 +88,18 @@ def display_results(request, image_id):
         'output_image_url': "/media/" + os.path.basename(output_image_path),
         'misplaced_objects': misplaced_objects
     })
+
+def display_video_results(request, video_id):
+    # Placeholder for video processing results view
+    video = get_object_or_404(UploadedVideo, id=video_id)
+    video_path = video.video.path
+
+    # Here you would run video analysis, currently, it's a placeholder
+    detected_objects = []  # Replace with actual video detection logic
+    misplaced_objects = []  # Replace with actual video detection logic
+
+    return render(request, 'process_misplaced_manager/display_video_results.html', {
+        'video': video,
+        'detected_objects': detected_objects,
+        'misplaced_objects': misplaced_objects
+    })
diff --git a/README.md b/README.md
index 00459617fd07615054a22b220f08db79f9cfc44f..3e01936eb5db336d6e6323025cb511b64dc09f1f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,14 @@
 # Identification of Misplaced Items
 
+ngrok http 8080  
 
+
+
+
+docker-compose down
+docker-compose up -d 
+
+docker-compose up --build
 ## DATABASE
 
 ### Connect though terminal
@@ -74,9 +82,9 @@ docker-compose exec web python manage.py migrate
 
 create superuser:
 
-``` bash
+``` bashhttps://wrb.uwe.ac.uk/Scientia/Portal/Login.aspx?ReturnUrl=%2fScientia%2fPortal%2fMain.aspx
 
- docker-compose exec web python manage.py createsuperuser
+docker-compose exec web python manage.py createsuperuser
 ```