varunv2004's picture
Create app.py
c897073 verified
import cv2
import numpy as np
from ultralytics import YOLO
import gradio as gr
import tempfile
import os
model = YOLO("yolov8n.pt")
def detect_lanes(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, 50, 150)
height, width = edges.shape
roi = np.array([[
(int(0.2 * width), height),
(int(0.8 * width), height),
(int(0.6 * width), int(0.6 * height)),
(int(0.4 * width), int(0.6 * height))
]], dtype=np.int32)
mask = np.zeros_like(edges)
cv2.fillPoly(mask, roi, 255)
masked_edges = cv2.bitwise_and(edges, mask)
# Use Hough Line Transform to detect lines
lines = cv2.HoughLinesP(
masked_edges,
rho=1,
theta=np.pi / 180,
threshold=50,
minLineLength=50,
maxLineGap=200
)
# Create an image to draw the lines on
line_image = np.zeros_like(image)
# Filter and average the lines for left and right lanes
left_lines = []
right_lines = []
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
slope = (y2 - y1) / (x2 - x1) if x2 != x1 else 0
if abs(slope) < 0.5: # Ignore near-horizontal lines
continue
if slope < 0: # Left lane
left_lines.append((x1, y1, x2, y2))
else: # Right lane
right_lines.append((x1, y1, x2, y2))
def average_lines(lines):
if len(lines) == 0:
return None
x_coords = []
y_coords = []
for line in lines:
x_coords += [line[0], line[2]]
y_coords += [line[1], line[3]]
poly_fit = np.polyfit(y_coords, x_coords, 1)
y1 = height
y2 = int(height * 0.6)
x1 = int(np.polyval(poly_fit, y1))
x2 = int(np.polyval(poly_fit, y2))
return x1, y1, x2, y2
left_lane = average_lines(left_lines)
right_lane = average_lines(right_lines)
# Draw the lanes
if left_lane:
cv2.line(line_image, (left_lane[0], left_lane[1]), (left_lane[2], left_lane[3]), (0, 255, 0), 5)
if right_lane:
cv2.line(line_image, (right_lane[0], right_lane[1]), (right_lane[2], right_lane[3]), (0, 255, 0), 5)
# Overlay the lines on the original image
result = cv2.addWeighted(image, 0.8, line_image, 1, 0)
return result
# YOLO Object Detection Function
def detect_objects(image):
results = model(image)
annotated_frame = results[0].plot() # Annotate the frame with bounding boxes
return annotated_frame
def process_image(image):
image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
detected_objects = detect_objects(image)
lane_detected = detect_lanes(image)
return cv2.cvtColor(detected_objects, cv2.COLOR_BGR2RGB), cv2.cvtColor(lane_detected, cv2.COLOR_BGR2RGB)
def process_video(video):
cap = cv2.VideoCapture(video.name)
output_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name
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))
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
detected_objects = detect_objects(frame)
# Lane detection
lane_detected = detect_lanes(frame)
# Combine detections and lane detection
combined_frame = cv2.addWeighted(detected_objects, 0.5, lane_detected, 0.5, 0)
out.write(combined_frame)
cap.release()
out.release()
return output_path
with gr.Blocks() as demo:
gr.Markdown("# YOLO Object Detection and Lane Detection")
with gr.Tab("Image Upload"):
image_input = gr.Image(label="Upload Image", type="pil")
object_output = gr.Image(label="Object Detection Output")
lane_output = gr.Image(label="Lane Detection Output")
image_button = gr.Button("Process Image")
image_button.click(process_image, inputs=image_input, outputs=[object_output, lane_output])
with gr.Tab("Video Upload"):
video_input = gr.Video(label="Upload Video")
video_output = gr.Video(label="Processed Video")
video_button = gr.Button("Process Video")
video_button.click(process_video, inputs=video_input, outputs=video_output)
demo.launch()