В современном быстро меняющемся мире заторы на дорогах, вызванные неожиданными дорожными препятствиями, могут привести к значительным задержкам и неудобствам для пассажиров. Чтобы решить эту проблему, мы разработали практическое решение с использованием компьютерного зрения и машинного обучения. В этой статье мы рассмотрим программу Python, которая использует YOLOv8, расширенную модель обнаружения объектов, а также библиотеку Ultralytics для обнаружения крупного рогатого скота на дорогах и упреждающего предотвращения пробок. Давайте углубимся и изучим код этой инновационной системы.

Введение

Заторы на дорогах — распространенная проблема на дорогах, часто вызванная неожиданными препятствиями, такими как бродячий скот. Подобные ситуации не только нарушают транспортный поток, но и представляют опасность как для водителей, так и для самих животных. Чтобы смягчить эти проблемы, мы разработали систему обнаружения крупного рогатого скота, которая идентифицирует крупный рогатый скот на дорогах и предупреждает соответствующие органы власти, позволяя им принять немедленные меры. Эта система использует возможности YOLOv8 для обнаружения объектов в реальном времени и Ultralytics для расширенной обработки моделей.

Предварительные требования

Прежде чем углубиться в код, давайте кратко обсудим необходимые условия и библиотеки, используемые в этом проекте:

- OpenCV: известная библиотека компьютерного зрения, предоставляющая инструменты для обработки изображений и видео.
- argparse: библиотека для анализа аргументов командной строки, обеспечивающая простую настройку. поведения программы.
 – Ultralytics: расширение моделей обнаружения объектов на основе PyTorch, предназначенное для упрощения развертывания и использования моделей.
 – NumPy: Фундаментальный пакет для научных вычислений на Python.

Пояснение кода

Теперь давайте разберем код шаг за шагом, чтобы понять, как работает эта система обнаружения крупного рогатого скота.

Импорт необходимых библиотек

python
# Importing necessary libraries
import cv2
import argparse
import time
from ultralytics import YOLO
import supervision as sv
import numpy as np
from sendmail import sendmail

Мы начнем с импорта основных библиотек, включая OpenCV, argparse для анализа аргументов командной строки, time для операций синхронизации, YOLO от Ultralytics для обнаружения объектов, контроля управления зонами, NumPy для числовых операций и sendmail для отправки уведомлений по электронной почте.

Определение полигона зоны

# Defining the polygon representing the zone of interest
ZONE_POLYGON = np.array([
 [0, 0],
 [0.5, 0],
 [0.75, 1],
 [0, 1]
])

Мы определяем полигон, который очерчивает интересующую область на дороге, где обнаружение крупного рогатого скота имеет решающее значение. Этот полигон служит границей для идентификации крупного рогатого скота в пределах указанной территории.

Анализ аргументов командной строки

# Parsing command-line arguments
def parse_arguments() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="YOLOv8 live")
    parser.add_argument(
        "--webcam-resolution", 
        default=[1280, 720], 
        nargs=2, 
        type=int
    )
    args = parser.parse_args()
    return args

Функция parse_argumetsфункция использует argparse для обработки аргументов командной строки. Пользователи могут указать желаемое разрешение веб-камеры в качестве аргумента для настройки поведения программы.

Инициализация системы

# Initializing the cattle detection system
def main():
    args = parse_arguments()
    frame_width, frame_height = args.webcam_resolution
    IP = 'http://192.168.192.20:8080/video'
    cap = cv2.VideoCapture(IP)
    if not cap.isOpened():
        print("Error: Could not open camera.")
        exit()
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)

    model = YOLO("yolov8l.pt")

    # ...

В функции main мы настраиваем систему, настраивая канал веб-камеры с помощью OpenCV. Видеопоток получается с определенного IP-адреса. Мы также устанавливаем разрешение камеры на основе ввода пользователя. Кроме того, мы загружаем модель YOLOv8, используя предварительно обученный файл контрольных точек («yolov8l.pt»).

Аннотирование обнаруженного крупного рогатого скота

    # Creating a box annotator for detected objects
    box_annotator = sv.BoxAnnotator(
        thickness=2,
        text_thickness=2,
        text_scale=1
    )

    # ...

Мы создаем экземпляр BoxAnnotator из библиотеки Ultralytics. Этот аннотатор помогает нам визуализировать обнаруженный крупный рогатый скот, рисуя вокруг него ограничивающие рамки и добавляя описательные метки.

Создание зоны и аннотатора

    # Creating a zone polygon and annotator for the zone
    zone_polygon = (ZONE_POLYGON * np.array(args.webcam_resolution)).astype(int)
    zone = sv.PolygonZone(polygon=zone_polygon, frame_resolution_wh=tuple(args.webcam_resolution))
    zone_annotator = sv.PolygonZoneAnnotator(
        zone=zone, 
        color=sv.Color.red(),
        thickness=2,
        text_thickness=4,
        text_scale=2
    )

    # ...

Мы определяем зону на дороге в виде полигона, используя предопределенные координаты. Эта зона используется для обнаружения крупного рогатого скота в ее пределах. Кроме того, мы создаем PolygonZoneAnnotator, чтобы визуально выделить зону в видеопотоке, чтобы ее было легче распознать.

Обнаружение в реальном времени и отслеживание зон

# Continuous processing of video frames
    while True:
        ret, frame = cap.read()

        result = model(frame, agnostic_nms=True)[0]
        detections = sv.Detections.from_yolov8(result)
        detections = detections[detections.class_id == 19]
        labels = [
            f"cattle {confidence:0.2f}"
            for _, confidence, class_id, _
            in detections
        ]
        frame = box_annotator.annotate(
            scene=frame, 
            detections=detections, 
            labels=labels
        )

        zone.trigger(detections=detections)
        frame = zone_annotator.annotate(scene=frame)      
        count_in_zone = len(detections)

        # ...

Внутри основного цикла мы обрабатываем каждый кадр изображения с веб-камеры. Модель YOLOv8 применяется для обнаружения объектов, и сохраняются только обнаружения крупного рогатого скота. Вокруг обнаруженного крупного рогатого скота рисуются ограничивающие рамки и метки с помощью box_annotator.

Функция Trigger() объекта Zone отслеживает обнаружение крупного рогатого скота в пределах определенной зоны. Затем используется Zone_annotator для маркировки зоны в кадре. Регистрируется подсчет крупного рогатого скота, обнаруженного в зоне.

Управление подсчетом скота и отслеживанием времени

# Handling cattle count and time tracking
        if count_in_zone > 0 and start_time is None:
            start_time = time.time()

        if count_in_zone == 0 and start_time is not None:
            end_time = time.time()
            elapsed_time = (end_time - start_time)
            print("Count reached 0. Elapsed time:", elapsed_time, "seconds")
            start_time = None

        n = time.time()
        if start_time is not None and ((n - start_time) > 5):
            sendmail(IP)
            start_time = None

        print(count_in_zone)
        cv2.imshow("yolov8", frame)

        if (cv2.waitKey(30) == 27):
            break

Этот раздел управляет подсчетом крупного рогатого скота и отслеживает время, прошедшее с момента последнего обнаружения крупного рогатого скота. Если обнаружен крупный рогатый скот, а время начала не установлено, время начала записывается. Если счетчик падает до нуля, прошедшее время рассчитывается и отображается.

Кроме того, если крупный рогатый скот обнаруживается более 5 секунд, уведомление по электронной почте отправляется с помощью функции sendmail().

Запуск программы

if __name__ == "__main__":
    main()

Наконец, мы выполняем функцию main() при непосредственном запуске скрипта. При этом запускается система обнаружения крупного рогатого скота и начинается обработка видеопотока.

sendmail.py

import smtplib

def sendmail(IP):
    sender_email = "[email protected]"
    sender_password = "pnceguck"
    receiver_email = "[email protected]"
    subject = "Road Blocked by Cattle!"
    message = "road blocked by cattle at the following location of the IP camera: "+IP


    def send_email(sender_email, sender_password, receiver_email, subject, message):
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.starttls()
        server.login(sender_email, sender_password)

        email_message = f"Subject: {subject}\n\n{message}"

        server.sendmail(sender_email, receiver_email, email_message)

        server.quit()

        print("Email sent successfully!")

    send_email(sender_email, sender_password, receiver_email, subject, message)

Заключение

В этой статье мы продемонстрировали, как создать систему обнаружения крупного рогатого скота с использованием YOLOv8 и Ultralytics. Используя обнаружение объектов, управление зонами и уведомления по электронной почте, эта система может заранее идентифицировать крупный рогатый скот на дорогах и уведомлять власти, чтобы предотвратить потенциальные пробки. Поняв код и концепции, представленные здесь, вы сможете применять аналогичные методы для решения различных реальных задач с помощью компьютерного зрения и машинного обучения. Приятного кодирования и решения проблем!