欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python基于YOLOv8和OpenCV實現(xiàn)車道線和車輛檢測功能

 更新時間:2025年01月15日 09:51:31   作者:old_power  
使用YOLOv8(You Only Look Once)和OpenCV實現(xiàn)車道線和車輛檢測,目標(biāo)是創(chuàng)建一個可以檢測道路上的車道并識別車輛的系統(tǒng),并估計它們與攝像頭的距離,這篇文章主要介紹了Python基于YOLOv8和OpenCV實現(xiàn)車道線和車輛檢測,需要的朋友可以參考下

使用YOLOv8(You Only Look Once)和OpenCV實現(xiàn)車道線和車輛檢測,目標(biāo)是創(chuàng)建一個可以檢測道路上的車道并識別車輛的系統(tǒng),并估計它們與攝像頭的距離。該項目結(jié)合了計算機視覺技術(shù)和深度學(xué)習(xí)物體檢測。

1、系統(tǒng)主要功能

  • 車道檢測:使用邊緣檢測和霍夫線變換檢測道路車道。
  • 汽車檢測:使用 YOLOv8 模型識別汽車并在汽車周圍繪制邊界框。
  • 距離估計:使用邊界框大小計算檢測到的汽車與攝像頭的距離。

2、環(huán)境要求

  • OpenCV:用于圖像處理和車道檢測。
  • Ultralytics YOLOv8:用于車輛檢測。
  • NumPy:用于數(shù)組操作。
pip install opencv-python-headless numpy ultralytics

opencv-pythonopencv-python-headless 區(qū)別是 OpenCV 的 Python 包,主要區(qū)別在于是否包含 GUI 相關(guān)的功能。

opencv-python

  • 包含 GUI 功能:支持窗口顯示、鼠標(biāo)事件等圖形界面操作。
  • 依賴:需要 GUI 庫(如 GTK、Qt)支持。
  • 適用場景:適用于需要顯示圖像或與用戶交互的環(huán)境,如桌面應(yīng)用。

opencv-python-headless

  • 不包含 GUI 功能:去除了窗口顯示和用戶交互功能。
  • 依賴:無需 GUI 庫,適合無圖形界面的環(huán)境。
  • 適用場景:適用于服務(wù)器或無圖形界面的環(huán)境,如遠(yuǎn)程服務(wù)器、Docker 容器。

3、代碼

import cv2
import numpy as np
import math
import time
from ultralytics import YOLO  # YOLOv8 module
# Function to mask out the region of interest
def region_of_interest(img, vertices):
    mask = np.zeros_like(img)
    match_mask_color = 255
    cv2.fillPoly(mask, vertices, match_mask_color)
    masked_image = cv2.bitwise_and(img, mask)
    return masked_image
# Function to draw the filled polygon between the lane lines
def draw_lane_lines(img, left_line, right_line, color=[0, 255, 0], thickness=10):
    line_img = np.zeros_like(img)
    poly_pts = np.array([[
        (left_line[0], left_line[1]),
        (left_line[2], left_line[3]),
        (right_line[2], right_line[3]),
        (right_line[0], right_line[1])
    ]], dtype=np.int32)
    # Fill the polygon between the lines
    cv2.fillPoly(line_img, poly_pts, color)
    # Overlay the polygon onto the original image
    img = cv2.addWeighted(img, 0.8, line_img, 0.5, 0.0)
    return img
# The lane detection pipeline
def pipeline(image):
    height = image.shape[0]
    width = image.shape[1]
    region_of_interest_vertices = [
        (0, height),
        (width / 2, height / 2),
        (width, height),
    ]
    # Convert to grayscale and apply Canny edge detection
    gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    cannyed_image = cv2.Canny(gray_image, 100, 200)
    # Mask out the region of interest
    cropped_image = region_of_interest(
        cannyed_image,
        np.array([region_of_interest_vertices], np.int32)
    )
    # Perform Hough Line Transformation to detect lines
    lines = cv2.HoughLinesP(
        cropped_image,
        rho=6,
        theta=np.pi / 60,
        threshold=160,
        lines=np.array([]),
        minLineLength=40,
        maxLineGap=25
    )
    # Separating left and right lines based on slope
    left_line_x = []
    left_line_y = []
    right_line_x = []
    right_line_y = []
    if lines is None:
        return image
    for line in lines:
        for x1, y1, x2, y2 in line:
            slope = (y2 - y1) / (x2 - x1) if (x2 - x1) != 0 else 0
            if math.fabs(slope) < 0.5:  # Ignore nearly horizontal lines
                continue
            if slope <= 0:  # Left lane
                left_line_x.extend([x1, x2])
                left_line_y.extend([y1, y2])
            else:  # Right lane
                right_line_x.extend([x1, x2])
                right_line_y.extend([y1, y2])
    # Fit a linear polynomial to the left and right lines
    min_y = int(image.shape[0] * (3 / 5))  # Slightly below the middle of the image
    max_y = image.shape[0]  # Bottom of the image
    if left_line_x and left_line_y:
        poly_left = np.poly1d(np.polyfit(left_line_y, left_line_x, deg=1))
        left_x_start = int(poly_left(max_y))
        left_x_end = int(poly_left(min_y))
    else:
        left_x_start, left_x_end = 0, 0  # Defaults if no lines detected
    if right_line_x and right_line_y:
        poly_right = np.poly1d(np.polyfit(right_line_y, right_line_x, deg=1))
        right_x_start = int(poly_right(max_y))
        right_x_end = int(poly_right(min_y))
    else:
        right_x_start, right_x_end = 0, 0  # Defaults if no lines detected
    # Create the filled polygon between the left and right lane lines
    lane_image = draw_lane_lines(
        image,
        [left_x_start, max_y, left_x_end, min_y],
        [right_x_start, max_y, right_x_end, min_y]
    )
    return lane_image
# Function to estimate distance based on bounding box size
def estimate_distance(bbox_width, bbox_height):
    # For simplicity, assume the distance is inversely proportional to the box size
    # This is a basic estimation, you may use camera calibration for more accuracy
    focal_length = 1000  # Example focal length, modify based on camera setup
    known_width = 2.0  # Approximate width of the car (in meters)
    distance = (known_width * focal_length) / bbox_width  # Basic distance estimation
    return distance
# Main function to read and process video with YOLOv8
def process_video():
    # Load the YOLOv8 model
    model = YOLO('weights/yolov8n.pt')
    # 或者加載官方模型
    # model = YOLO("yolov8n.pt")  # load an official model
    # Open the video file
    cap = cv2.VideoCapture('video/video.mp4')
    # Check if video opened successfully
    if not cap.isOpened():
        print("Error: Unable to open video file.")
        return
    # Set the desired frame rate
    target_fps = 30
    frame_time = 1.0 / target_fps  # Time per frame to maintain 30fps
    # Resize to 720p (1280x720)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
    # Loop through each frame
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        # Resize frame to 720p
        resized_frame = cv2.resize(frame, (1280, 720))
        # Run the lane detection pipeline
        lane_frame = pipeline(resized_frame)
        # Run YOLOv8 to detect cars in the current frame
        results = model(resized_frame)
        # Process the detections from YOLOv8
        for result in results:
            boxes = result.boxes
            for box in boxes:
                x1, y1, x2, y2 = map(int, box.xyxy[0])  # Bounding box coordinates
                conf = box.conf[0]  # Confidence score
                cls = int(box.cls[0])  # Class ID
                # Only draw bounding boxes for cars with confidence >= 0.5
                if model.names[cls] == 'car' and conf >= 0.5:
                    label = f'{model.names[cls]} {conf:.2f}'
                    # Draw the bounding box
                    cv2.rectangle(lane_frame, (x1, y1), (x2, y2), (0, 255, 255), 2)
                    cv2.putText(lane_frame, label, (x1, y1 - 10),
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2)
                    # Estimate the distance of the car
                    bbox_width = x2 - x1
                    bbox_height = y2 - y1
                    distance = estimate_distance(bbox_width, bbox_height)
                    # Display the estimated distance
                    distance_label = f'Distance: {distance:.2f}m'
                    cv2.putText(lane_frame, distance_label, (x1, y2 + 20),
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
        # Display the resulting frame with both lane detection and car detection
        cv2.imshow('Lane and Car Detection', lane_frame)
        # Limit the frame rate to 30fps
        time.sleep(frame_time)
        # Break the loop when 'q' is pressed
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    # Release video capture and close windows
    cap.release()
    cv2.destroyAllWindows()
# Run the video processing function
process_video()

4、工作原理

4.1 車道線檢測 Pipeline

車道線檢測包括一下幾個步驟:

Step 1: 屏蔽感興趣區(qū)域(ROI)
只處理圖像的下半部分(車道線通常是可見的)。

def region_of_interest(img, vertices):
    mask = np.zeros_like(img)
    match_mask_color = 255
    cv2.fillPoly(mask, vertices, match_mask_color)
    masked_image = cv2.bitwise_and(img, mask)
    return masked_image

Step 2: 使用Canny進(jìn)行邊緣檢測
將圖像轉(zhuǎn)換為灰度,并應(yīng)用Canny邊緣檢測來突出顯示邊緣。

gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
cannyed_image = cv2.Canny(gray_image, 100, 200)

Step 3: 霍夫線變換
霍夫線變換用于檢測當(dāng)前車道的線段。

lines = cv2.HoughLinesP(
    cropped_image,
    rho=6,
    theta=np.pi / 60,
    threshold=160,
    lines=np.array([]),
    minLineLength=40,
    maxLineGap=25
)

4.2 使用YOLOv8進(jìn)行車輛檢測

Step 1: 加載YOLOv8模型
我們使用預(yù)訓(xùn)練的YOLOv8模型來檢測每一幀中的汽車(或者使用官方提供的模型)。

from ultralytics import YOLO
model = YOLO('weights/yolov8n.pt')
# model = YOLO('yolov8n.pt') #官方提供的模型

Step 2: 繪制邊界框
對于每一輛檢測到的汽車,繪制邊界框,并顯示類名(汽車)和置信度分?jǐn)?shù)。

for box in boxes:
    x1, y1, x2, y2 = map(int, box.xyxy[0])
    conf = box.conf[0]
    if model.names[cls] == 'car' and conf >= 0.5:
        label = f'{model.names[cls]} {conf:.2f}'
        cv2.rectangle(lane_frame, (x1, y1), (x2, y2), (0, 255, 255), 2)
        cv2.putText(lane_frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2)

Step 3:. 距離估計
根據(jù)邊界框的大小估計到每輛檢測到的汽車的距離。

def estimate_distance(bbox_width, bbox_height):
    focal_length = 1000  # Example focal length
    known_width = 2.0  # Approximate width of a car (in meters)
    distance = (known_width * focal_length) / bbox_width
    return distance

Step 4:. 視頻處理 Pipeline
將車道檢測、車輛檢測和距離估計結(jié)合到一個實時視頻處理pipeline中。

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    lane_frame = pipeline(resized_frame)
    results = model(resized_frame)
    for result in results:
        # Draw bounding boxes and estimate distance
    cv2.imshow('Lane and Car Detection', lane_frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

5、結(jié)果

項目源碼地址: https://github.com/CityIsBetter/Lane_Detection

到此這篇關(guān)于Python基于YOLOv8和OpenCV實現(xiàn)車道線和車輛檢測的文章就介紹到這了,更多相關(guān)Python YOLOv8和OpenCV車道線檢測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論