Untitled
unknown
python
2 years ago
7.7 kB
4
Indexable
import cv2 import os import matplotlib.pyplot as plt from calibration_utils import calibrate_camera, undistort from binarization_utils import binarize from perspective_utils import birdeye from line_utils import get_fits_by_sliding_windows, draw_back_onto_the_road, Line, get_fits_by_previous_fits import numpy as np from globals import xm_per_pix, time_window # YOLOv4 setup net = cv2.dnn.readNet("yolov4.weights", "yolov4.cfg") net.setPreferableTarget(cv2.dnn.DNN_TARGET_OPENCL_FP16) classes = [] with open("coco.names", "r") as f: classes = [line.strip() for line in f.readlines()] print(classes) confidence_threshold = 0.5 nms_threshold = 0.4 processed_frames = 0 line_lt = Line(buffer_len=time_window) line_rt = Line(buffer_len=time_window) def detect_objects(frame): height, width, channels = frame.shape # Convert frame to blob for input to neural network blob = cv2.dnn.blobFromImage(frame, 1/255, (416, 416), (0, 0, 0), swapRB=True, crop=False) # Set input for neural network net.setInput(blob) # Get output layer names layer_names = net.getLayerNames() output_layers = [layer_names[layer_id - 1] for layer_id in net.getUnconnectedOutLayers()] # Run forward pass through neural network outputs = net.forward(output_layers) # Initialize variables for object detection boxes = [] confidences = [] class_ids = [] # Loop through outputs and detect objects for output in outputs: for detection in output: scores = detection[5:] class_id = np.argmax(scores) confidence = scores[class_id] if confidence > confidence_threshold: center_x = int(detection[0] * width) center_y = int(detection[1] * height) w = int(detection[2] * width) h = int(detection[3] * height) # Rectangle coordinates x = int(center_x - w / 2) y = int(center_y - h / 2) boxes.append([x, y, w, h]) confidences.append(float(confidence)) class_ids.append(class_id) # Apply non-maximum suppression to eliminate overlapping boxes indices = cv2.dnn.NMSBoxes(boxes, confidences, confidence_threshold, nms_threshold) near_color =(0, 0, 255) # Red far_color = (0, 255, 0) # Green text_color = (255, 255, 255) # Loop through indices and draw boxes and labels around objects if len(indices) > 0: for i in indices.flatten(): box = boxes[i] x, y, w, h = box # Determine center of box center_x = int(x + w / 2) center_y = int(y + h / 2) # Determine if object is near or far based on y position if center_y < 400: color = far_color text = "FAR" else: color = near_color text = "NEAR" # Draw box and label on frame cv2.rectangle(frame, (x, y), (x + w, y + h), color, thickness=3) cv2.putText(frame, f"{classes[class_ids[i]]} {confidences[i]:.2f} {text}", (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, text_color, thickness=2) return frame def prepare_out_blend_frame(blend_on_road, img_binary, img_birdeye, img_fit, line_lt, line_rt, offset_meter): h, w = blend_on_road.shape[:2] thumb_ratio = 0.2 thumb_h, thumb_w = int(thumb_ratio * h), int(thumb_ratio * w) off_x, off_y = 20, 15 # add a gray rectangle to highlight the upper area mask = blend_on_road.copy() mask = cv2.rectangle(mask, pt1=(0, 0), pt2=(w, thumb_h+2*off_y), color=(0, 0, 0), thickness=cv2.FILLED) blend_on_road = cv2.addWeighted(src1=mask, alpha=0.2, src2=blend_on_road, beta=0.8, gamma=0) # add thumbnail of binary image thumb_binary = cv2.resize(img_binary, dsize=(thumb_w, thumb_h)) thumb_binary = np.dstack([thumb_binary, thumb_binary, thumb_binary]) * 255 blend_on_road[off_y:thumb_h+off_y, off_x:off_x+thumb_w, :] = thumb_binary # add thumbnail of bird's eye view thumb_birdeye = cv2.resize(img_birdeye, dsize=(thumb_w, thumb_h)) thumb_birdeye = np.dstack([thumb_birdeye, thumb_birdeye, thumb_birdeye]) * 255 blend_on_road[off_y:thumb_h+off_y, 2*off_x+thumb_w:2*(off_x+thumb_w), :] = thumb_birdeye # add thumbnail of bird's eye view (lane-line highlighted) thumb_img_fit = cv2.resize(img_fit, dsize=(thumb_w, thumb_h)) blend_on_road[off_y:thumb_h+off_y, 3*off_x+2*thumb_w:3*(off_x+thumb_w), :] = thumb_img_fit # add text (curvature and offset info) on the upper right of the blend mean_curvature_meter = np.mean([line_lt.curvature_meter, line_rt.curvature_meter]) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(blend_on_road, 'Curvature radius: {:.02f}m'.format(mean_curvature_meter), (860, 60), font, 0.9, (255, 255, 255), 2, cv2.LINE_AA) cv2.putText(blend_on_road, 'Offset from center: {:.02f}m'.format(offset_meter), (860, 130), font, 0.9, (255, 255, 255), 2, cv2.LINE_AA) return blend_on_road def process_pipeline(frame, keep_state=True): global line_lt, line_rt, processed_frames img_undistorted = undistort(frame, mtx, dist, verbose=False) img_binary = binarize(img_undistorted, verbose=False) img_birdeye, M, Minv = birdeye(img_binary, verbose=False) # Lane detection if processed_frames > 0 and keep_state and line_lt.detected and line_rt.detected: line_lt, line_rt, img_fit = get_fits_by_previous_fits(img_birdeye, line_lt, line_rt, verbose=False) else: line_lt, line_rt, img_fit = get_fits_by_sliding_windows(img_birdeye, line_lt, line_rt, n_windows=9, verbose=False) # Object detection frame_with_objects = detect_objects(frame.copy()) offset_meter = compute_offset_from_center(line_lt, line_rt, frame_width=frame.shape[1]) blend_on_road = draw_back_onto_the_road(img_undistorted, Minv, line_lt, line_rt, keep_state) # Overlay object detection on top of lane detection blend_on_road = cv2.addWeighted(src1=blend_on_road, alpha=0.5, src2=frame_with_objects, beta=1, gamma=0) blend_output = prepare_out_blend_frame(blend_on_road, img_binary, img_birdeye, img_fit, line_lt, line_rt, offset_meter) processed_frames += 1 return blend_output def compute_offset_from_center(line_lt, line_rt, frame_width): if line_lt.detected and line_rt.detected: line_lt_bottom = np.mean(line_lt.all_x[line_lt.all_y > 0.95 * line_lt.all_y.max()]) line_rt_bottom = np.mean(line_rt.all_x[line_rt.all_y > 0.95 * line_rt.all_y.max()]) lane_width = line_rt_bottom - line_lt_bottom midpoint = frame_width / 2 offset_pix = abs((line_lt_bottom + lane_width / 2) - midpoint) offset_meter = xm_per_pix * offset_pix else: offset_meter = -1 return offset_meter if __name__ == '__main__': # first things first: calibrate the camera ret, mtx, dist, rvecs, tvecs = calibrate_camera(calib_images_dir='camera_cal') # Open the webcam cap = cv2.VideoCapture("input_video/input_video3.mp4") # 0 for default camera, you may need to change it based on your system while True: # Capture frame-by-frame ret, frame = cap.read() # Process the frame blend = process_pipeline(frame, keep_state=False) # Display the resulting frame cv2.imshow('Frame', blend) # Break the loop if 'q' key is pressed if cv2.waitKey(1) & 0xFF == ord('q'): break # When everything is done, release the capture cap.release() cv2.destroyAllWindows()
Editor is loading...
Leave a Comment