According to Earth.org, over 100,000 marine animals die each year due to plastic pollution in our oceans. This alarming statistic inspired me to take action. I developed an Object Detection AI named OceanWatch using a public dataset from Kaggle and the YOLOv8 model. OceanWatch is designed to detect pollution in aquatic environments. When pollution is identified, the AI alerts a designated phone number and sends the last five seconds of footage, enabling quick and accurate identification of the pollution source.
To ensure this solution is portable and functional beyond a laptop, I'm utilizing Raspberry Pi hardware paired with a Raspberry Pi camera to detect ocean water pollution in real-time.
To validate the accuracy of this object detection AI, I used a video for testing since I don’t have access to an ocean for live trials. You can view the side-by-side comparison here:
https://drive.google.com/file/d/10C56BenBvfAIFT_f99V1LIioOJgab7a_/preview
Here is my code for the camera detection:
import os
import time
from collections import deque
from datetime import datetime, timedelta
from threading import Thread
import cv2
from ultralytics import YOLO
from email_send_v1 import send_mail
model_path = os.path.join('.', 'runs', 'detect', 'train2', 'weights', 'best.pt')
model = YOLO(model_path)
input_video_path = r"filepath.mp4"
cap = cv2.VideoCapture(input_video_path)
threshold = 0.5
fps = cap.get(cv2.CAP_PROP_FPS)
buffer_size = int(fps * 5)
frame_buffer = deque(maxlen=buffer_size)
last_video_time = None
cooldown_time = timedelta(seconds=5)
output_folder = 'sending_videos'
os.makedirs(output_folder, exist_ok=True)
def save_video(buffer, fps):
if len(buffer) == 0:
return
height, width, _ = buffer[0][1].shape
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_path = os.path.join(output_folder, f'{timestamp}.mp4')
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
for _, frame in buffer:
out.write(frame)
out.release()
send_mail(fr"sending_videos\\{timestamp}.mp4", 1)
def cleanup_old_videos():
while True:
now = time.time()
for filename in os.listdir(output_folder):
file_path = os.path.join(output_folder, filename)
if os.path.isfile(file_path):
file_age = now - os.path.getmtime(file_path)
if file_age > 60:
os.remove(file_path)
time.sleep(30)
cleanup_thread = Thread(target=cleanup_old_videos, daemon=True)
cleanup_thread.start()
while True:
ret, frame = cap.read()
frame_buffer.append((time.time(), frame.copy()))
results = model(frame)[0]
for result in results.boxes.data.tolist():
x1, y1, x2, y2, score, class_id = result
if score > threshold and class_id != 1:
cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 4)
cv2.putText(frame, results.names[int(class_id)].upper(), (int(x1), int(y1 - 10)), cv2.FONT_HERSHEY_SIMPLEX,
1.3, (0, 255, 0), 3, cv2.LINE_AA)
current_time = datetime.now()
if (last_video_time is None or current_time - last_video_time >= cooldown_time) and len(
frame_buffer) >= buffer_size:
save_thread = Thread(target=save_video, args=(list(frame_buffer), fps))
save_thread.start()
frame_buffer.clear()
last_video_time = current_time
resized_frame = cv2.resize(frame, (800, 450))
cv2.imshow('OceanWatch', resized_frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Here is my code for sending the text message:
import os
import smtplib
import ssl
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from moviepy.editor import VideoFileClip
def compress_video(file_path):
clip = VideoFileClip(file_path)
width, height = clip.size
if height > 720:
clip_resized = clip.resize(height=360)
compressed_path = file_path.replace(".mp4", "_compressed.mp4")
clip_resized.write_videofile(compressed_path, codec="libx264")
return compressed_path
else:
return file_path
def send_mail(file_path, cameranum):
sender_mail = "[email protected]"
receiver_mail = "[email protected]"
subject = "Litter Detected!"
body = (f"Litter has been detected from Camera #{cameranum}. Please dispatch cleaning officers to prevent "
f"further damage to the environment.")
password = "password"
if file_path.lower().endswith(('.mp4', '.avi', '.mov', '.mkv')):
file_path = compress_video(file_path)
message = MIMEMultipart()
message["From"] = sender_mail
message["To"] = receiver_mail
message["Subject"] = subject
message.attach(MIMEText(body, "plain"))
with open(file_path, "rb") as attachment:
part = MIMEBase("application", "octet-stream")
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header("Content-Disposition", f"attachment; filename= {os.path.basename(file_path)}")
message.attach(part)
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
server.login(sender_mail, password)
server.sendmail(sender_mail, receiver_mail, message.as_string())