Parking Monitoring System via Video Analytics

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1 servicesAll 1566 services
Parking Monitoring System via Video Analytics
Medium
~5 business days
FAQ
AI Development Areas
AI Solution Development Stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823
  • image_logo-aider_0.jpg
    AIDER company logo development
    762
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    848

System Development мониторинга парковки через видеоаналитику

Система видеоаналитики парковки заменяет дорогостоящие ультразвуковые и магнитные датчики на каждое машиноместо единой камерой, покрывающей несколько рядов. Задачи: определение занятости мест в реальном времени, подсчёт свободных/занятых мест, трекинг автомобилей, интеграция с системой навигации по парковке.

Определение занятости машиномест

from ultralytics import YOLO
import numpy as np
import cv2
import json

class ParkingMonitor:
    def __init__(self, model_path: str, parking_config_path: str):
        self.detector = YOLO(model_path)  # детекция автомобилей
        self.parking_spaces = self._load_parking_config(parking_config_path)

    def _load_parking_config(self, config_path: str) -> list[dict]:
        """Загрузка конфигурации машиномест (полигоны зон)"""
        with open(config_path) as f:
            config = json.load(f)

        spaces = []
        for space in config['spaces']:
            spaces.append({
                'id': space['id'],
                'polygon': np.array(space['polygon'], dtype=np.int32),
                'zone': space.get('zone', 'default')
            })
        return spaces

    def analyze(self, frame: np.ndarray) -> dict:
        """Определение занятости всех машиномест"""
        detections = self.detector(frame, conf=0.4,
                                    classes=[2, 5, 7])  # car, bus, truck

        # Определяем центры обнаруженных ТС
        vehicle_centers = []
        for box in detections[0].boxes.xyxy:
            x1, y1, x2, y2 = map(int, box)
            cx, cy = (x1 + x2) // 2, (y1 + y2) // 2
            vehicle_centers.append((cx, cy))

        # Проверяем каждое машиноместо
        occupied_spaces = []
        free_spaces = []

        for space in self.parking_spaces:
            occupied = self._is_space_occupied(space['polygon'],
                                                vehicle_centers,
                                                detections[0].boxes.xyxy)
            space_status = {
                'id': space['id'],
                'zone': space['zone'],
                'occupied': occupied
            }

            if occupied:
                occupied_spaces.append(space_status)
            else:
                free_spaces.append(space_status)

        return {
            'total_spaces': len(self.parking_spaces),
            'occupied': len(occupied_spaces),
            'free': len(free_spaces),
            'occupancy_rate': len(occupied_spaces) / max(len(self.parking_spaces), 1),
            'spaces': occupied_spaces + free_spaces
        }

    def _is_space_occupied(self, polygon: np.ndarray,
                            vehicle_centers: list,
                            vehicle_boxes: list) -> bool:
        """Проверка: есть ли транспортное средство на машиноместе"""
        # Метод 1: центр ТС внутри полигона
        for cx, cy in vehicle_centers:
            result = cv2.pointPolygonTest(polygon, (float(cx), float(cy)), False)
            if result >= 0:
                return True

        # Метод 2: overlap bounding box с полигоном > 40%
        space_mask = np.zeros((720, 1280), dtype=np.uint8)
        cv2.fillPoly(space_mask, [polygon], 255)
        space_area = cv2.contourArea(polygon)

        for box in vehicle_boxes:
            x1, y1, x2, y2 = map(int, box)
            vehicle_mask = np.zeros_like(space_mask)
            cv2.rectangle(vehicle_mask, (x1, y1), (x2, y2), 255, -1)

            intersection = cv2.bitwise_and(space_mask, vehicle_mask)
            overlap = intersection.sum() / 255

            if overlap / space_area > 0.4:
                return True

        return False

Разметка машиномест

Первоначальная разметка зон машиномест выполняется один раз через веб-интерфейс:

class ParkingSpaceLabeler:
    """Интерактивная разметка машиномест на кадре"""
    def __init__(self, image_path: str):
        self.image = cv2.imread(image_path)
        self.spaces = []
        self.current_polygon = []

    def interactive_label(self):
        """Запуск интерактивной разметки (для ручного использования)"""
        cv2.namedWindow('Label Parking Spaces')
        cv2.setMouseCallback('Label Parking Spaces', self._on_click)

        while True:
            display = self.image.copy()
            for space in self.spaces:
                cv2.polylines(display, [space['polygon']], True, (0, 255, 0), 2)
            if self.current_polygon:
                cv2.polylines(display,
                              [np.array(self.current_polygon)], False, (0, 0, 255), 2)
            cv2.imshow('Label Parking Spaces', display)

            key = cv2.waitKey(1)
            if key == ord('s') and len(self.current_polygon) >= 4:
                self.spaces.append({
                    'id': f'space_{len(self.spaces)+1}',
                    'polygon': self.current_polygon.copy()
                })
                self.current_polygon = []
            elif key == ord('q'):
                break

        return self.spaces

Integration с системой навигации

  • Digital signage: экраны с картой парковки, обновление в реальном времени
  • Мобильное приложение: бронирование мест, навигация к свободному месту
  • Умные светофоры: зелёный/красный индикатор над каждым рядом
  • ANPR интеграция: автоматический въезд/выезд по номеру, расчёт стоимости

Metrics системы

Параметр Значение
Точность определения занятости 96–99%
Latency обновления < 5 секунд
Камер на 1 GPU 8–16 (зависит от разрешения)
Машиномест на камеру 10–50 (зависит от ракурса)
Ложные определения занятости < 2%
Масштаб системы Срок
1–4 камеры, 50–200 мест 3–4 недели
10–20 камер, многоуровневая 6–9 недель
Enterprise, навигация + API 10–16 недель