0% found this document useful (0 votes)
8 views46 pages

Pothole Detection System Project Code Explanation

The document outlines a web application for pothole detection using AI and camera input, detailing the code structure and libraries involved. Key components include user authentication, camera handling, and alarm functionality, with a focus on real-time detection using the YOLO model. The application is designed to efficiently manage camera connections and log events for troubleshooting.

Uploaded by

sivavanapalli59
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views46 pages

Pothole Detection System Project Code Explanation

The document outlines a web application for pothole detection using AI and camera input, detailing the code structure and libraries involved. Key components include user authentication, camera handling, and alarm functionality, with a focus on real-time detection using the YOLO model. The application is designed to efficiently manage camera connections and log events for troubleshooting.

Uploaded by

sivavanapalli59
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 46

Pothole Detection System: A

Comprehensive Explanation
Introduction to the System
This code creates a web application that can detect potholes using a camera or uploaded videos.
The system uses artificial intelligence to recognize potholes in real-time and can even sound an
alarm when potholes are detected.

Import Section Explanation


The first part of the code imports various libraries and tools needed for the application to work:

from flask import Flask, render_template, Response, request,


redirect, url_for, flash, session, jsonify

This imports Flask, which is like the foundation for building web applications. Think of Flask as
the skeleton of your website.

from flask_login import LoginManager, UserMixin, login_user,


login_required, logout_user, current_user

This brings in tools to handle user logins and security. It's like having a security guard for your
website who checks IDs.

import cv2

OpenCV (cv2) is a computer vision library. Think of it as the "eyes" of your application that can
process and understand images and videos.

import winsound

This is used to play alarm sounds on Windows computers when potholes are detected.
from ultralytics import YOLO

YOLO is the AI model that actually detects potholes in images. Think of it as the "brain" that
recognizes what a pothole looks like.

import time
import os
import platform
import logging

These are utilities for timing operations, working with files and directories, identifying the
operating system, and keeping track of what's happening (logging).

from werkzeug.utils import secure_filename

This helps make sure that uploaded file names are safe to use and won't cause security
problems.

import numpy as np

NumPy is used for mathematical operations on arrays, which is helpful when processing image
data.

import threading

Threading allows your program to do multiple things at once, like processing video while also
serving web pages.

from typing import Optional, Union, List

These help with type hints to make the code more reliable and easier to understand.

from datetime import datetime

This is used to record when potholes are detected.

import requests
Used for making HTTP requests, which might be needed when connecting to cameras over the
network.

import socket
import netifaces

These help identify and work with network interfaces and IP addresses, useful for connecting to
cameras over a network.

Logging Setup

logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

This sets up logging to keep track of what happens in the application. It's like having a diary that
records important events with timestamps. This can help you troubleshoot problems later.

Directory Structure Setup

current_dir = os.path.dirname(os.path.abspath(__file__))
template_dir = os.path.join(current_dir, 'templates')
static_dir = os.path.join(current_dir, 'static')
uploads_dir = os.path.join(static_dir, 'uploads')
logs_dir = os.path.join(current_dir, 'logs')

for directory in [uploads_dir, logs_dir]:


os.makedirs(directory, exist_ok=True)

This code sets up the necessary folders for your application:


●​ It finds where your application is currently located
●​ It creates paths for templates (web page designs), static files (like images, CSS), uploads
(for video files), and logs
●​ It makes sure these directories exist, creating them if they don't
Think of this as organizing your workspace before starting a project.
Flask Application Setup

app = Flask(__name__,
template_folder=template_dir,
static_folder=static_dir)
app.secret_key = os.environ.get('FLASK_SECRET_KEY',
'your_secret_key_here')
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max file
size

This creates your Flask web application:


●​ It tells Flask where to find templates and static files
●​ It sets a secret key for security (used for sessions and cookies)
●​ It limits uploaded files to 16MB to prevent server overload
The secret key is like a password that your application uses to encrypt sensitive data.

User Authentication Setup

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'

class User(UserMixin):
def __init__(self, id):
self.id = id
self.name = id

@staticmethod
def get(user_id):
if user_id not in users:
return None
return User(user_id)

users = {
'admin': {'password': 'admin123'}
}

This sets up the login system:


●​ It creates a login manager to handle authentication
●​ It defines a User class to represent users in your system
●​ It sets up a simple user database with one user (admin/admin123)
Think of this as creating an entry system where only people with the right credentials can access
the application.

YOLO Model Loading

try:
model_path = os.path.join(current_dir,
'runs/detect/pothole_detector/weights/best.pt')
model = YOLO(model_path)
logger.info("YOLO model loaded successfully")
except Exception as e:
logger.error(f"Error loading YOLO model: {str(e)}")
raise

This loads the pothole detection AI model:


●​ It tries to load the YOLO model from a specific file location
●​ If successful, it logs a success message
●​ If it fails, it logs the error and stops the application
The model is what enables your application to actually recognize potholes in images.

Detection Configuration

class DetectionConfig:
CONF_THRESHOLD = 0.45
IOU_THRESHOLD = 0.45
MIN_AREA_RATIO = 0.01
MAX_AREA_RATIO = 0.5
ALARM_COOLDOWN = 2

This class defines settings for pothole detection:


●​ CONF_THRESHOLD: How confident the AI needs to be to call something a pothole
(45%)
●​ IOU_THRESHOLD: Used to avoid duplicate detections of the same pothole
●​ MIN_AREA_RATIO and MAX_AREA_RATIO: Size limits for pothole detection to
ignore very small or very large objects
●​ ALARM_COOLDOWN: Minimum time (2 seconds) between alarm sounds to avoid
constant beeping
Think of these as the sensitivity settings for your pothole detector.
Camera Handler Class
This is a complex class that manages different camera types and connections. I'll break it down
section by section:

class CameraHandler:
def __init__(self):
self.camera = None
self.current_source = None
self.last_alarm_time = 0
self.is_mobile = False
self.camera_lock = threading.Lock()
self.connection_timeout = 10
self.retry_delay = 1
self.ivcam_connection_retries = 3
self.client_ip = None

This initializes the camera handler with default settings:


●​ It starts with no camera connected
●​ It tracks when the last alarm was played
●​ It uses a lock to prevent multiple parts of the code from accessing the camera at the same
time
●​ It sets various timeouts and retry settings for connecting to cameras
Think of this as setting up the control panel for your camera system.

def get_camera_source(self, is_mobile, client_ip):


"""Determine appropriate camera source based on device type and
network"""
if is_mobile:
# If accessing from mobile, try iVCam first
if self.test_ivcam_connection(client_ip):
return 'ivcam'
# Fallback to IP camera if iVCam fails
if self.test_ip_camera_connection():
return 'ip'
# Default to system camera for non-mobile or if other options
fail
return 'system'

This method decides which camera to use:


●​ For mobile devices, it first tries to use iVCam (a phone camera app)
●​ If that fails, it tries a standard IP camera
●​ If all else fails, it uses the computer's built-in camera
This is like having a smart system that chooses the best available camera depending on what
devices are connected.

def get_all_network_ips(self):
"""Get all possible IP addresses in the network"""
# [Implementation details]

This method scans the network for possible IP addresses where cameras might be connected.
Think of it as looking around your network neighborhood to find cameras.

def test_ivcam_connection(self, client_ip):


"""Test if iVCam is available on the client's IP"""
url = 'http://192.168.1.11:4747/video'
return self.test_connection(url)

This tests if an iVCam camera is available at a specific IP address. Note that there's a hardcoded
IP address here (192.168.1.11).

def test_ip_camera_connection(self):
"""Test if IP camera is available"""
url = 'http://192.168.1.3:8080/video'
return self.test_connection(url)

Similarly, this tests if a regular IP camera is available at another hardcoded address


(192.168.1.3).

def test_connection(self, url, timeout=1):


"""Test camera connection with timeout"""
try:
cap = cv2.VideoCapture(url)
if cap.isOpened():
ret, frame = cap.read()
cap.release()
return ret and frame is not None
return False
except:
return False

This method tries to actually connect to a camera and grab a frame to see if it's working. Think
of it as checking if a camera is actually on and sending images.
Camera Handler Class Methods
initialize_camera Method

def initialize_camera(self, source_type='system', is_mobile=False,


client_ip=None):
"""Initialize camera with improved error handling"""
with self.camera_lock:

This starts a function that sets up the camera. The with self.camera_lock: creates a
protected section where only one part of the program can access the camera at a time.

if self.camera is not None:


self.release_camera()

If there's already an active camera, this shuts it down first before setting up a new one.

self.is_mobile = is_mobile
self.client_ip = client_ip
logger.info(f"Initializing camera - Source: {source_type},
Mobile: {is_mobile}, Client IP: {client_ip}")

This saves information about the device connecting and writes a log message with these
details.

try:
# Determine the best camera source
if source_type == 'auto':
source_type = self.get_camera_source(is_mobile,
client_ip)

This tries to automatically pick the best camera type if 'auto' was selected.
if source_type == 'system':
return self._init_system_camera()
elif source_type == 'ivcam':
return self._init_ivcam_camera()
elif source_type == 'ip':
return self._init_ip_camera()
else:
raise ValueError(f"Invalid camera source type:
{source_type}")

This calls the appropriate setup function based on which camera type was chosen.

except Exception as e:
logger.error(f"Camera initialization error: {str(e)}")
return False

If anything goes wrong during setup, this catches the error, logs it, and returns False to indicate
failure.

_init_system_camera Method

def _init_system_camera(self):
"""Initialize system camera with retry logic"""
for idx in range(2): # Try first two camera indices

This function starts a loop to try the first two camera devices (0 and 1).

for _ in range(3): # Retry 3 times

For each camera device, it tries connecting up to 3 times.

try:
camera = cv2.VideoCapture(idx, cv2.CAP_DSHOW)

This creates a connection to the camera. cv2.CAP_DSHOW uses DirectShow on Windows for
better compatibility.
if self._verify_camera(camera):
self.camera = camera
self.current_source = 'system'
return True

If the camera passes the verification test, it's saved as the active camera and the function
returns success.

camera.release()

If verification fails, the camera resources are released.

except Exception as e:
logger.error(f"System camera error: {str(e)}")

Any errors are caught and logged.

time.sleep(1)

The code waits for 1 second before retrying.

return False

After all attempts fail, the function returns False.

_init_ivcam_camera Method

def _init_ivcam_camera(self):
"""Initialize iVCam with improved connection handling"""
url = 'http://192.168.1.11:4747/video' # Updated IP and port
logger.info(f"Attempting to connect to iVCam at: {url}")

This sets the network address for the iVCam app and logs the connection attempt.
# url = f'http://{self.client_ip}:8080/video'
# logger.info(f"Attempting to connect to iVCam at: {url}")

These commented lines show an alternative way to connect using the client's own IP address.

try:
camera = cv2.VideoCapture()

This creates a camera connection object.

camera.set(cv2.CAP_PROP_BUFFERSIZE, 3)
camera.set(cv2.CAP_PROP_FOURCC,
cv2.VideoWriter_fourcc(*'MJPG'))
camera.set(cv2.CAP_PROP_FPS, 30)

These lines configure the camera settings:

●​ Buffer size of 3 frames


●​ MJPG video format
●​ 30 frames per second

camera.open(url)

This attempts to open the connection to the camera using the provided URL.

if self._verify_camera(camera):
self.camera = camera
self.current_source = 'ivcam'
logger.info(f"Successfully connected to iVCam at {url}")
return True

If verification succeeds, the camera is saved and the function returns success.

camera.release()

If verification fails, resources are released.


except Exception as e:
logger.error(f"Failed to connect to iVCam: {str(e)}")

Any errors are caught and logged.

return False

Returns failure if the connection couldn't be established.

_init_ip_camera Method

def _init_ip_camera(self):
"""Initialize IP camera connection"""
url = 'http://192.168.1.3:8080/video'

This sets the network address for the IP camera.

try:
camera = cv2.VideoCapture()
camera.set(cv2.CAP_PROP_BUFFERSIZE, 3)
camera.set(cv2.CAP_PROP_FOURCC,
cv2.VideoWriter_fourcc(*'MJPG'))
camera.set(cv2.CAP_PROP_FPS, 30)
camera.open(url)

This creates and configures the camera connection, similar to the iVCam setup.

if self._verify_camera(camera):
self.camera = camera
self.current_source = 'ip'
return True

If verification succeeds, the camera is saved and the function returns success.

camera.release()
If verification fails, resources are released.

except Exception as e:
logger.error(f"Failed to connect to IP camera: {str(e)}")

Any errors are caught and logged.

return False

Returns failure if the connection couldn't be established.

_verify_camera Method

def _verify_camera(self, camera):


"""Verify camera is working with improved checks"""
if not camera.isOpened():
return False

This first checks if the camera is actually open.

success_count = 0
start_time = time.time()

These variables track successful frame reads and the start time for the verification process.

while time.time() - start_time < 3: # 3 second timeout

This loop runs for up to 3 seconds.

ret, frame = camera.read()

This tries to read a frame from the camera.


if ret and frame is not None and frame.size > 0:
success_count += 1
if success_count >= 3: # Need 3 successful frames
return True

If a valid frame is read, the success count increases. Once 3 frames are successfully read, the
camera is considered working.

time.sleep(0.1)

The code waits 0.1 seconds between frame attempts.

return False

If 3 successful frames aren't captured within 3 seconds, verification fails.

release_camera Method

def release_camera(self):
"""Release camera resources safely"""
with self.camera_lock:
try:
if self.camera is not None:
self.camera.release()
self.camera = None
self.current_source = None
logger.info("Camera released successfully")

This safely releases the camera resources and clears related variables.

except Exception as e:
logger.error(f"Error releasing camera: {str(e)}")

Any errors are caught and logged.

Alarm Functions
def play_alarm():
"""Platform-specific alarm implementation"""
try:
if platform.system() == 'Windows':
winsound.Beep(1000, 500)
time.sleep(0.1)
winsound.Beep(2000, 500)

This plays two beeps at different frequencies (1000Hz and 2000Hz) for 500 milliseconds each,
with a small pause in between, but only on Windows.

else:
logger.info("Alarm triggered - sound not available on
non-Windows systems")

On non-Windows systems, it just logs that an alarm was triggered.

except Exception as e:
logger.error(f"Error playing alarm: {str(e)}")

Any errors are caught and logged.

def should_play_alarm(camera_handler):
current_time = time.time()
if current_time - camera_handler.last_alarm_time >=
DetectionConfig.ALARM_COOLDOWN:
camera_handler.last_alarm_time = current_time
return True
return False

This checks if enough time has passed since the last alarm to play a new one.

def play_alarm_if_needed(camera_handler):
if should_play_alarm(camera_handler):
alarm_thread = threading.Thread(target=play_alarm)
alarm_thread.daemon = True
alarm_thread.start()
If an alarm should be played, this starts it in a separate thread so it doesn't interrupt the main
program.

Pothole Detection Functions

def is_valid_detection(detection, frame_shape):


try:
conf = float(detection.conf[0])
box = detection.xyxy[0]

This extracts the confidence level and bounding box from a detection.

box_area = (box[2] - box[0]) * (box[3] - box[1])


frame_area = frame_shape[0] * frame_shape[1]
area_ratio = box_area / frame_area

This calculates how much of the frame is occupied by the detected object.

return (conf >= DetectionConfig.CONF_THRESHOLD and


DetectionConfig.MIN_AREA_RATIO <= area_ratio <=
DetectionConfig.MAX_AREA_RATIO)

This returns True if the detection meets confidence and size requirements.

except Exception as e:
logger.error(f"Error validating detection: {str(e)}")
return False

Any errors are caught, logged, and the detection is considered invalid.

def process_frame(frame, camera_handler):


try:
results = model(frame)[0]
detections = []

This runs the AI model on a frame and prepares a list to store detection information.
if len(results.boxes) > 0:
valid_detections = [box for box in results.boxes if
is_valid_detection(box, frame.shape)]

This filters out invalid detections.

if valid_detections:
play_alarm_if_needed(camera_handler)

If there are valid detections, an alarm may be played.

for box in valid_detections:


conf = float(box.conf[0])
x1, y1, x2, y2 = map(int, box.xyxy[0])

For each valid detection, this extracts the confidence and coordinates.

cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255),


3)

This draws a red rectangle around the pothole.

label = f'Pothole {conf:.2f}'


(w, h), _ = cv2.getTextSize(label,
cv2.FONT_HERSHEY_SIMPLEX, 0.6, 2)
cv2.rectangle(frame, (x1, y1-20), (x1 + w, y1), (0,
0, 255), -1)
cv2.putText(frame, label, (x1, y1-5),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255,
255), 2)

This adds a label with the confidence level.

detections.append({
'confidence': conf,
'box': (x1, y1, x2, y2),
'timestamp': datetime.now().isoformat()
})

This saves the detection information.

return frame, detections

This returns the processed frame and detection data.

except Exception as e:
logger.error(f"Error processing frame: {str(e)}")
return frame, []

Any errors are caught and logged, returning the original frame and empty detections.

Video Streaming Functions

camera_handler = CameraHandler()

This creates a global camera handler object.

def generate_frames():
try:
while True:
with camera_handler.camera_lock:
if camera_handler.camera is None:
break

This starts a loop that continues as long as there's an active camera.

success, frame = camera_handler.camera.read()


if not success:
break
This reads a frame from the camera and stops if reading fails.

frame, detections = process_frame(frame,


camera_handler)

This processes the frame to detect potholes.

ret, buffer = cv2.imencode('.jpg', frame)


if not ret:
continue

This converts the frame to JPEG format.

frame = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame +
b'\r\n')

This yields the frame in a format suitable for web streaming.

except Exception as e:
logger.error(f"Error in generate_frames: {str(e)}")

Any errors are caught and logged.

finally:
camera_handler.release_camera()

Camera resources are released when the function ends.

Web Application Routes


User Authentication
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)

This tells the login system how to load a user from their ID.

Main Routes

@app.route('/')
def home():
return redirect(url_for('login'))

This sends visitors from the homepage to the login page.

@app.route('/login', methods=['GET', 'POST'])


def login():
if current_user.is_authenticated:
return redirect(url_for('index'))

If a user is already logged in, this sends them to the main application.

if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')

This gets the username and password from a login form.

if username in users and users[username]['password'] ==


password:
user = User(username)
login_user(user)
next_page = request.args.get('next')
return redirect(next_page or url_for('index'))

If the login details are valid, the user is logged in and sent to the requested page or main page.

flash('Invalid username or password')


If login fails, an error message is shown.

return render_template('login.html')

For initial visits, the login form is displayed.

@app.route('/index')
@login_required
def index():
# Enhanced mobile detection
user_agent = request.headers.get('User-Agent', '').lower()
is_mobile = any(device in user_agent for device in [
'mobile', 'android', 'iphone', 'ipad', 'ipod',
'webos', 'blackberry', 'windows phone'
])

This checks if the user is on a mobile device by looking at their browser information.

return render_template('index.html', is_mobile=is_mobile)

This shows the main application page, with a flag indicating if the user is on mobile.

Camera Control Routes

@app.route('/start_camera/<source_type>')
@login_required
def start_camera(source_type):
try:
# Enhanced client detection
user_agent = request.headers.get('User-Agent', '').lower()
is_mobile = any(device in user_agent for device in [
'mobile', 'android', 'iphone', 'ipad', 'ipod',
'webos', 'blackberry', 'windows phone'
])
client_ip = request.remote_addr

This determines the device type and gets the user's IP address.
# Log connection attempt
logger.info(f"Camera start request - Source: {source_type}")
logger.info(f"Client Info - IP: {client_ip}, Mobile:
{is_mobile}")
logger.info(f"User Agent: {user_agent}")

This logs details about the connection attempt.

# Auto-select camera source if needed


if source_type == 'auto':
if is_mobile:
# Try iVCam first for mobile devices
if camera_handler.test_ivcam_connection(client_ip):
source_type = 'ivcam'
# Fallback to IP camera
elif camera_handler.test_ip_camera_connection():
source_type = 'ip'
else:
source_type = 'system'
else:
source_type = 'system'

This selects the appropriate camera type based on the device.

# Initialize camera
success = camera_handler.initialize_camera(source_type,
is_mobile, client_ip)

This initializes the selected camera.

if success:
return jsonify({
'status': 'success',
'source': source_type,
'is_mobile': is_mobile
})

If initialization succeeds, success information is returned.


else:
error_msg = {
'status': 'error',
'message': 'Failed to initialize camera',
'details': {
'source': source_type,
'is_mobile': is_mobile,
'client_ip': client_ip
}
}
logger.error(f"Camera initialization failed:
{error_msg}")
return jsonify(error_msg), 500

If initialization fails, error information is returned.

except Exception as e:
logger.error(f"Error starting camera: {str(e)}")
return jsonify({'status': 'error', 'message': str(e)}), 500

Any errors are caught, logged, and returned as a response.

Camera Status Route

@app.route('/check_camera_status')
@login_required
def check_camera_status():
"""Check if camera is connected and working"""
try:
if camera_handler.camera is None:
return jsonify({
'status': 'disconnected',
'source': None,
'is_mobile': camera_handler.is_mobile
})

If there's no active camera, this returns 'disconnected' status.


ret, _ = camera_handler.camera.read()
if ret:
return jsonify({
'status': 'connected',
'source': camera_handler.current_source,
'is_mobile': camera_handler.is_mobile
})

If a frame can be read, this returns 'connected' status.

else:
return jsonify({
'status': 'error',
'message': 'Camera not reading frames',
'source': camera_handler.current_source,
'is_mobile': camera_handler.is_mobile
})

If the camera exists but can't read frames, this returns an error.

except Exception as e:
return jsonify({
'status': 'error',
'message': str(e),
'source': camera_handler.current_source,
'is_mobile': camera_handler.is_mobile
})

Any errors are caught and returned as a response.

Video Stream Route

@app.route('/video_feed')
@login_required
def video_feed():
try:
return Response(generate_frames(),
mimetype='multipart/x-mixed-replace;
boundary=frame')
This creates a continuous video stream using the frame generator.

except Exception as e:
logger.error(f"Error in video_feed: {str(e)}")
return "Camera error", 500

Any errors are caught, logged, and returned as a response.

Video Upload Route

@app.route('/upload_video', methods=['POST'])
@login_required
def upload_video():
if 'video' not in request.files:
return jsonify({'error': 'No video file'}), 400

video_file = request.files['video']
if video_file.filename == '':
return jsonify({'error': 'No selected file'}), 400

This checks that a video was actually uploaded.

try:
filename = secure_filename(video_file.filename)
video_path = os.path.join(uploads_dir, filename)
video_file.save(video_path)

This saves the uploaded video with a secure filename.

output_filename = f'processed_{filename}'
output_path = os.path.join(uploads_dir, output_filename)

This defines a filename for the processed video.

cap = cv2.VideoCapture(video_path)
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))

This opens the video and gets its properties.

out = cv2.VideoWriter(output_path,
cv2.VideoWriter_fourcc(*'mp4v'),
fps,
(frame_width, frame_height))

This creates a video writer for the processed video.

while True:
success, frame = cap.read()
if not success:
break

frame, detections = process_frame(frame, camera_handler)


out.write(frame)

This processes each frame for potholes and writes it to the output video.

cap.release()
out.release()

This closes the input and output videos.

if os.path.exists(video_path):
os.remove(video_path)

This deletes the original uploaded video to save space.

processed_video_url = url_for('static',

filename=f'uploads/{output_filename}')
return jsonify({
'status': 'success',
'processed_video': processed_video_url
})

This returns a link to the processed video.

except Exception as e:
logger.error(f"Error processing video: {str(e)}")
return jsonify({'error': str(e)}), 500

Any errors are caught, logged, and returned as a response.

Camera Stop Route

@app.route('/stop_camera', methods=['POST'])
@login_required
def stop_camera():
try:
camera_handler.release_camera()
return jsonify({
'status': 'success',
'message': 'Camera stopped successfully'
})

This stops the camera and returns a success message.

except Exception as e:
logger.error(f"Error stopping camera: {str(e)}")
return jsonify({
'status': 'error',
'message': str(e)
}), 500

Any errors are caught, logged, and returned as a response.

Logout Route

@app.route('/logout')
@login_required
def logout():
try:
camera_handler.release_camera()

This releases the camera before logging out.

except Exception as e:
logger.error(f"Error during logout camera cleanup: {str(e)}")

Any errors are caught and logged.

logout_user()
return redirect(url_for('login'))

This logs the user out and redirects to the login page.

Unauthorized Handler

@login_manager.unauthorized_handler
def unauthorized():
flash('You must be logged in to access this page.')
return redirect(url_for('login'))

This shows a message and redirects to login when someone tries to access a protected page
without logging in.

Application Startup

if __name__ == '__main__':
try:
# Add configuration for handling larger video files
app.config['MAX_CONTENT_LENGTH'] = 64 * 1024 * 1024 # 64MB
max file size

This sets the maximum file upload size to 64MB.


# Start the Flask application
app.run(debug=True, port=5000, host='0.0.0.0', threaded=True)

This starts the web application with these settings:

●​ Debug mode enabled


●​ Running on port 5000
●​ Available on all network interfaces
●​ Threading enabled for multiple users

except Exception as e:
logger.error(f"Application error: {str(e)}")

Any startup errors are caught and logged.

finally:
camera_handler.release_camera()

Camera resources are released when the application exits.

This detailed breakdown shows how each line of code contributes to the complete pothole
detection system, from camera management to video processing to the web interface.
Files Explanination​

🚀

Core Application (Flask Web App & Detection Script)
File/Folder Purpose

app.py Main Flask app that launches the pothole detection web interface and
streams video with detection.

static/ Stores static assets like images, CSS, JS (used by Flask).

templates/ Contains HTML templates for the Flask app (e.g., index.html).

filter.bat Likely a script for filtering or running a specific function.

requirements. (Empty now) Used to list dependencies like Flask, OpenCV, etc., to set
txt up the project environment.

🎯 YOLO Training and Inference


File/Folder Purpose

train.py YOLO training script (probably uses ultralytics or custom


logic).

val.py Validation script to evaluate trained models.

train_manager Controls training process; logs, manages configs, etc.


.py

predict.py Runs inference (detection) on input data.

predict.py_ol Older version of the prediction script.


d

train.py_old Old version of training script.

yolov8n.pt YOLOv8 pre-trained model weights.


data.yaml YOLO training config file – defines dataset paths and class
names.

📁 Dataset Related
File/Folder Purpose

dataset/ Contains labeled images and annotation files for training.

input/ Might store test or real-time input images/videos.

backup_weigh Stores backup YOLO model weights during/after training.


ts/

🔍 Evaluation, Testing & Extra Tools


File/Folder Purpose

test.py, test_model.py, Testing scripts – test_iv.py is likely for iVCam support.


test_iv.py

monitor.py Monitors system or training progress (logs, memory, CPU,


etc.).

check_missing_labels.py Checks for missing labels in the dataset (helps clean


data).

cleanup.py Script to clean the dataset directory (e.g., remove


corrupted or unnecessary files).

📊 Logs and Monitoring


File/Folder Purpose

logs/ Likely stores internal logs or TensorBoard logs.

training_log_*.l Text log files of each training session – shows metrics, losses,
og etc.

system_monitor_* Logs CPU/GPU/memory usage during training.


.txt
🎥 Videos and Media
File Purpose

Capstone_project(Demo- Demo video showing detection or


1).mp4 results.

output_detection.mp4 Output video from model inference.

tested.mp4 Another test output or processed video.

p 374.jpg A single input image for testing/demo.

⚙️ Project Metadata
File/Folder Purpose

.gitignore Specifies files/folders to ignore in Git.

.gitattributes Defines Git attribute rules (line endings, etc.).

README.md Project overview and instructions (Markdown format).

package.json, Indicates usage of Node.js – maybe used for dashboard or


package-lock.json script installation.

node_modules/ Node.js dependencies (from npm install).

.venv/, venv/ Python virtual environments.

__pycache__/ Compiled Python files (auto-generated).

.ipynb_checkpoints/ Jupyter Notebook checkpoints.

labelenv/ Possibly used for labeling environments or managing


image-label data.
🧠
Tech Stack​
Model / AI Component
✅ YOLOv8 (Ultralytics)
●​ Framework: Ultralytics YOLOv8​

●​ File: yolov8n.pt (Pre-trained model weights)​

●​ Scripts:​

○​ train.py – Trains the model using YOLOv8 and your dataset.​

○​ val.py – Validates model performance.​

○​ predict.py – Runs object detection (inference) on images/video.​

○​ train_manager.py – Manages training sessions and logging.​

○​ data.yaml – Defines class names and dataset structure for YOLO.​

🖥️ Backend
✅ Flask (Python Web Framework)
●​ Main App File: app.py​

●​ Purpose: Serves the web interface, handles camera selection, runs live detection, plays
alarm sounds.​
●​ Folders:​

○​ templates/: HTML files for web UI (index.html, etc.)​

○​ static/: CSS, JS, or images for the UI.​

●​ Libraries Likely Used:​

○​ flask​

○​ opencv-python​

○​ ultralytics or torch​

○​ threading, playsound, os, cv2, etc.​

🎨 Frontend
✅ HTML + CSS + JavaScript via Flask
●​ Directory: templates/, static/​

●​ Function:​

○​ Web interface for live video stream​

○​ Camera selection UI​

○​ Display detection results from Flask backend​

🧪 Testing & Camera Support


✅ Script Support for Various Camera Inputs
●​ test.py – General testing (possibly webcam or video file detection)​

●​ test_iv.py – Custom script for iVCam/iPhone camera detection​

●​ test_model.py – Quick model test using saved inputs​

🔧 Utility Scripts
Script/File Purpose

monitor.py Logs CPU/GPU/memory usage during detection/training.

check_missing_labe Checks dataset for images without label files.


ls.py

cleanup.py Cleans dataset (e.g., removes unused images).

filter.bat Possibly a batch file to quickly run a task (e.g., launch app.py
or run detection).

requirements.txt (currently empty) Should list Python dependencies like Flask,


OpenCV, Ultralytics, etc.

📦 Environment & Dependency Management


✅ Python Virtual Environment
●​ Folder: .venv/, venv/​

●​ Isolates dependencies for this project​

●​ Created using: python -m venv venv​

✅ Node.js (Optional - Frontend Extras?)


●​ Files: package.json, package-lock.json, node_modules/​
●​ May have been used to add frontend interactivity or run build tools (like Webpack,
Parcel, or live server)​

📂 Dataset Management
Folder Purpose

dataset/ Your training images and YOLO format .txt labels

input/ Likely test inputs

backup_weigh Saved trained weights


ts/

logs/ Possibly TensorBoard or training-related logs

labelenv/ Possibly label-studio or related tool integration

runs/ Default YOLO output folder for training and detection results

📹 Media Output
File Purpose

Capstone_project(Demo-1).mp4, Recorded output of detection


output_detection.mp4, tested.mp4 pipeline

p 374.jpg Sample input image used in


testing

📜 Documentation & Version Control


File Purpose

README.md Contains project overview and usage (can be


improved)
.gitignore, Used to ignore files for Git repo version control
.gitattributes

✅ Summary Table
Component Technology Used Files/Folders

Model YOLOv8 yolov8n.pt, train.py, predict.py,


data.yaml

Backend Flask (Python) app.py, static/, templates/

Frontend HTML, CSS, JS (via Flask) templates/, static/

Camera Support OpenCV + iVCam test.py, test_iv.py

Monitoring Custom Logging Scripts monitor.py, system_monitor_*.txt

Dataset Custom + YOLO format dataset/, labelenv/, input/

Env Mgmt Python venv + Node.js venv/, package.json, .venv/,


node_modules/

Utilities Label checker, cleanup check_missing_labels.py,


cleanup.py
Sample Questions​

🔧

Project Architecture & Tech Stack

Q1. What is the overall architecture of your project?​


A:​
Our project follows a modular architecture:

●​ Frontend: Flask-based web UI to interact with the model.​

●​ Backend: YOLOv8 model running detection in real time.​

●​ Scripts: Python scripts handle training, inference, camera streams, logging, and
monitoring.​

●​ Storage: Local file system to store input videos, logs, and output results.​

Q2. Which technologies and frameworks have you used in this project?​
A:

●​ YOLOv8 from the Ultralytics library for pothole detection.​

●​ Flask for building the web interface.​

●​ OpenCV to process video streams and webcam feed.​

●​ Playsound for alert notifications.​


●​ Python scripting for model training, monitoring, and detection logic.​

Q3. Why did you choose YOLOv8 for this task?​


A:​
YOLOv8 is lightweight, accurate, and supports real-time detection. It provides faster inference
on low-end devices and has great support for custom training with our pothole dataset.

📸 Detection & Dataset


Q4. How did you collect and prepare the dataset?​
A:​
We gathered ~700+ images of real road conditions using open datasets and screenshots from
street surveillance. We labeled them using LabelImg, converting them into YOLO format and
verified using a script to check for missing labels.

Q5. How does your system handle different camera inputs?​


A:​
We have a CameraHandler class that supports:

●​ System webcam (default),​

●​ IP Webcam from Android phones,​

●​ iVCam from iPhones.​


The user can choose the camera type from the interface.​

Q6. What are the limitations of your model?​


A:

●​ Limited dataset size may reduce accuracy in diverse environments.​

●​ False positives may occur with shadows or patches on roads.​

●​ Needs GPU for faster real-time detection on high-res video.​


🧠 Model Training & Accuracy
Q7. How did you train the model and for how many epochs?​
A:​
We trained using Ultralytics YOLOv8 CLI for 50 epochs on a custom dataset. The training
script (train.py) logs accuracy, precision, recall, and loss at each stage.

Q8. How do you evaluate the model's performance?​


A:​
We use metrics like:

●​ mAP (mean Average Precision)​

●​ Precision and Recall​

●​ Visual inspection on new videos or webcam feed​


Also, logs from val.py and system monitor files are used for review.​

🌐 Flask App & Real-Time Detection


Q9. How does the Flask app work in your project?​
A:​
The app.py file starts a Flask server, handles user authentication, and allows selecting the
camera source. It streams detection results using OpenCV’s cv2.VideoCapture() and
displays output in real-time on the browser.

Q10. How is an alarm triggered during detection?​


A:​
When the model detects a pothole above a certain confidence threshold, the playsound
module plays an alarm sound, and a visual bounding box is drawn on the frame.

🧪 Testing & Deployment


Q11. How did you test your application?​
A:​
We tested:

●​ With sample videos (tested.mp4, output_detection.mp4)​

●​ On real-time webcam and mobile IP camera​

●​ Verified detection performance using labeled ground truth​

Q12. Can this project be deployed in real life?​


A:​
Yes, it can be deployed in smart surveillance systems, traffic cams, or drones to monitor roads
for maintenance. With a larger dataset and cloud deployment, it can scale city-wide.​


1. How is this project useful in the real world?

Answer:​
This project is a step toward improving road safety and reducing accidents caused by
potholes, which are a huge issue, especially in developing countries. Roads with potholes can
lead to vehicle damage, accidents, and traffic disruptions. Our system offers a quick, automated
way to detect potholes in real time, which can be used by municipalities, government
agencies, and road safety organizations to take action faster. It helps in reducing road
maintenance costs and preventing injuries from road-related accidents.

2. Are there already software solutions available in the market for pothole
detection?

Answer:​
Yes, there are some commercial solutions like Roadroid and StreetScan, but they often rely
on specialized equipment or manual data collection, which can be expensive and
time-consuming. They also may not provide real-time detection. Our solution offers a more
affordable, flexible, and scalable approach. It can use existing mobile cameras or simple
webcams, making it accessible even to small road maintenance teams. Moreover, it's designed
to be lightweight and easy to deploy.
3. What makes your project stand out from the existing solutions in the
market?

Answer:​
Our project stands out in several ways:

●​ Real-time Detection: Unlike most solutions that require pre-recorded data or long-term
analysis, our system detects potholes in real time as a video stream is captured. This
enables instant responses, making it ideal for proactive road maintenance.​

●​ Ease of Access: It doesn’t require high-end cameras or expensive sensors. We


leverage webcams, IP cameras, and even mobile phones to capture the video, making
it both cost-effective and easily deployable.​

●​ Integrated Alert System: Our system not only detects potholes but also alerts the user
immediately via an alarm. This makes it practical for use in vehicles, drones, or on-site
monitoring stations.​

●​ Flexibility: It's designed to be modular, meaning it can easily be integrated into different
platforms like web applications or mobile apps, providing high customization options
for various user needs.​

4. What social or environmental impact do you expect from this project?

Answer:​
The social impact is significant. By improving road safety and reducing accidents, this project
could save lives, minimize injuries, and make commuting safer for everyone. The
environmental impact is also noteworthy—keeping roads in good condition means fewer
vehicles breaking down or getting stuck in potholes, reducing emissions and fuel consumption
caused by vehicles detouring or idling on damaged roads.

5. Why did you choose this project? What motivated you?

Answer:​
We chose this project because potholes are an everyday problem in many regions, and there’s
a clear need for a solution that’s both effective and affordable. Seeing the negative impact
potholes have on road safety and the environment, we wanted to create a system that can be
easily adopted and used by road maintenance authorities, even in resource-constrained
areas. The potential to make a real difference in people's lives and reduce accidents was a
major motivation for us.
6. What future enhancements do you see for this project?

Answer:​
We plan to improve the model by:

●​ Expanding the dataset to include more diverse pothole scenarios.​

●​ Using drones for aerial pothole detection, allowing for large-scale monitoring of
highways.​

●​ Adding AI-based predictive analytics to not only detect potholes but predict areas
where potholes are likely to form based on weather, traffic, and road conditions.​

●​ Integrating the system with smart city infrastructure to enable automated road
repairs and more efficient traffic management.​

7. What impact does this have on the future of road infrastructure


management?

Answer:​
This project can revolutionize road infrastructure management by making it data-driven,
real-time, and more proactive. Instead of relying on periodic manual inspections, authorities
can now receive continuous updates and alerts about road conditions, leading to faster repairs,
better resource allocation, and lower costs for road maintenance. Over time, this could lead to
smarter cities with roads that are continuously monitored and maintained.







🛠️ Pothole Detection Using YOLOv8 – Project Summary


for New Teammates


🚧 What is this project about?
This project is about automatically detecting potholes on roads using a real-time object
detection model. Potholes are dangerous and can cause accidents, so this system helps
identify them quickly by analyzing video feeds.

🎯 Why did we build this?


●​ To improve road safety by spotting potholes early.​

●​ Manual inspection is slow and expensive—our model automates this.​

●​ Can be used by government agencies, traffic departments, or drone-based surveillance


to monitor roads.​

🧠 How does it work?


1.​ A YOLOv8 model is trained to recognize potholes in images.​

2.​ A live video stream (from a webcam or mobile camera) is given as input.​

3.​ The model processes each frame and highlights potholes with bounding boxes.​

4.​ When a pothole is detected, it raises an alert sound.​

5.​ The detection is shown in real-time through a web browser using a Flask web app.​

🧰 Technologies Used
Component Tool / Tech Used Purpose

Detection Model YOLOv8 (Ultralytics) Real-time pothole detection

Backend Python + Flask App logic and web interface

Video Handling OpenCV Process video input


Dataset LabelImg Annotating training images
Labeling

Alerts Playsound module To play alarm when pothole is found

Storage Local files and logs For storing detections, training logs, etc.

🧪 How was it developed?


1.​ Dataset Creation​
We collected around 100 images showing roads with potholes. We labeled the potholes
using a tool called LabelImg and saved the data in YOLO format.​

2.​ Model Training​


Using YOLOv8, we trained a custom object detection model with our labeled dataset.
We used logs to monitor training performance.​

3.​ Real-Time Detection App​


We built a Flask web app (app.py) that:​

○​ Lets the user choose a camera source (webcam, IP camera, iPhone camera)​

○​ Loads the trained model​

○​ Streams video with pothole detection​

○​ Raises an alarm on detection​

4.​ Extra Scripts​

○​ train.py: To train the model.​

○​ predict.py: For testing on images or videos.​

○​ monitor.py: For logging system performance.​

○​ check_missing_labels.py: To validate dataset labels.​

🌍 Where can this be used?


●​ Traffic monitoring systems​

●​ Drones scanning highways​

●​ Road inspection teams​

●​ Autonomous vehicles (as an add-on safety layer)​

✅ End Goal
To build an efficient, working system that can:

●​ Detect potholes in real-time​

●​ Alert users instantly​

●​ Help authorities maintain safer roads​








You might also like