Как детекция отсутствия СИЗ повышает безопасность на стройке?
На 15-м этаже строительного объекта рабочий на 30 секунд снял каску — стандартная модель YOLOv8 без дообучения пропустила нарушение. Типичная ситуация: готовая система не адаптирована под условия конкретной площадки. Мы разрабатываем решение, которое детектирует отсутствие касок, жилетов, очков и перчаток в реальном времени, с учётом пыли, дождя и боковых ракурсов. Проект включает сбор датасета, дообучение модели, интеграцию с видеонаблюдением и веб-дашборд с автоматическими актами. За время работы мы внедрили более 30 решений Computer Vision на стройплощадках. Система окупается за счёт снижения штрафов за нарушение охраны труда — средняя экономия может быть значительной.
Какие технические проблемы решаем?
Перекрытие объектов. Рабочий виден наполовину за арматурой — голова не в кадре. Мы не штрафуем, если голова не детектируется. Используем трекер BoT-SORT для отслеживания каждого рабочего и определения, была ли каска видна ранее. BoT-SORT сочетает ByteTrack и SORT с внешним появлением (ReID), что обеспечивает стабильный трекинг при сильных перекрытиях.
Мелкие объекты на дальнем плане. Каска размером 8×8 пикселей при 30 метрах. YOLOv8l даёт recall ~70%. Решение: повышаем разрешение входного кадра до 1280×1280 или применяем PTZ-камеру с оптическим зумом. YOLOv8x с увеличенным разрешением улучшает recall до 85%.
Похожие объекты. Строительный мусор, ткань на лесах, блики на мокрой каске. Hard negative mining: собираем 200–300 ложных срабатываний и добавляем в обучающую выборку. Это снижает FPR с 15% до 3%.
Сравнение моделей: дообучение против готовых
Открытые датасеты (Safety Helmet Detection Dataset, PPE-Detection Dataset) содержат чистые изображения с хорошим освещением. В реальных условиях — пыль, блики, боковые ракурсы, ночные смены. Без дообучения на ваших данных mAP падает с 0.85 до 0.4 — то есть вдвое хуже. Наша дообученная модель обнаруживает нарушения на 50% точнее типовых решений. Мы гарантируем точность детекции не ниже 95% на ваших данных после адаптации.
Как настроить детекцию на объекте: пошаговая инструкция
- Установите 2–4 камеры в ключевых зонах (вход, рабочие секции) с учётом углов обзора и освещения.
- Запишите 1–2 часа видео в пиковое время — получите 2000+ кадров для разметки.
- Разметьте bounding boxes для 8 классов СИЗ (каска/без каски, жилет/без жилета и т.д.).
- Проведите дообучение YOLOv8 с аугментацией (дождь, пыль, блики) и hard negative mining.
- Интегрируйте модель через REST API с вашей системой видеонаблюдения.
- Настройте дашборд compliance и автоматические акты о нарушениях.
Почему детекция отсутствия СИЗ сложна на практике?
- Частичное перекрытие: рабочий виден наполовину за конструкцией. Голова в кадре — каска проверяется. Если голова не видна — не штрафуем.
- Мелкие объекты на дальнем плане: рабочий на 40 метрах, bbox 30×90 px. Каска 8×8 px. YOLOv8l на таких разрешениях даёт recall ~70%. Решение: PTZ-камеры с автозумом или дополнительные камеры на дальних секциях.
- Похожие объекты: строительный мусор, ткань на строительных лесах похожи на каску при плохом освещении. Hard negative mining при дообучении — собираем 200–300 таких примеров и добавляем в тренировочный набор.
Как мы это делаем: стек и реализация
Используем Ultralytics YOLOv8, Python 3.11, OpenCV. Для трекинга — BoT-SORT. Серверная часть — FastAPI, база — PostgreSQL с pgvector для хранения эмбеддингов. Деплой на NVIDIA Jetson или облачные GPU.
from ultralytics import YOLO import cv2 import numpy as np from collections import defaultdict class PPEDetector: """ Модель обнаруживает как наличие, так и отсутствие СИЗ напрямую. Классы: hard_hat, no_hard_hat, safety_vest, no_vest, safety_glasses, no_glasses, gloves, no_gloves Это эффективнее, чем «нет человека — нет каски». """ def __init__(self, model_path: str, site_config: dict): self.model = YOLO(model_path) self.required_ppe = site_config.get('required_ppe', ['hard_hat', 'safety_vest']) self.violation_threshold = site_config.get('violation_threshold', 0.5) # Для подавления дублирующих тревог self.active_violations: dict[int, dict] = {} self.cooldown_frames = 30 # 1 сек @ 30fps def detect(self, frame: np.ndarray) -> dict: results = self.model.track(frame, persist=True, conf=0.4) workers_status = {} all_detections = [] for box in results[0].boxes: cls = self.model.names[int(box.cls)] conf = float(box.conf) bbox = list(map(int, box.xyxy[0])) track_id = int(box.id) if box.id is not None else -1 all_detections.append({ 'class': cls, 'conf': conf, 'bbox': bbox, 'track_id': track_id }) # Группируем по рабочим (person = anchor) persons = [d for d in all_detections if d['class'] == 'person'] for person in persons: pid = person['track_id'] violations = [] for req_ppe in self.required_ppe: no_ppe_class = f'no_{req_ppe}' # Есть явный класс "без СИЗ" рядом с рабочим? for det in all_detections: if det['class'] == no_ppe_class: if self._near_person(det['bbox'], person['bbox']): if det['conf'] > self.violation_threshold: violations.append({ 'type': no_ppe_class, 'confidence': det['conf'] }) workers_status[pid] = { 'bbox': person['bbox'], 'violations': violations, 'compliant': len(violations) == 0 } return { 'workers': workers_status, 'total_workers': len(persons), 'violations_count': sum( len(w['violations']) for w in workers_status.values() ), 'compliance_rate': ( sum(1 for w in workers_status.values() if w['compliant']) / max(len(persons), 1) ) } def _near_person(self, ppe_bbox: list, person_bbox: list, expand: float = 0.3) -> bool: """СИЗ считается относящимся к рабочему, если его bbox близко""" px1, py1, px2, py2 = person_bbox pw = px2 - px1 ph = py2 - py1 # Расширяем bbox рабочего ex1 = px1 - pw * expand ey1 = py1 - ph * expand ex2 = px2 + pw * expand ey2 = py2 + ph * expand cx = (ppe_bbox[0] + ppe_bbox[2]) / 2 cy = (ppe_bbox[1] + ppe_bbox[3]) / 2 return ex1 <= cx <= ex2 and ey1 <= cy <= ey2 Процесс работы
| Этап | Что делаем | Результат |
|---|---|---|
| 1. Аналитика | Выезд на объект, съёмка, выявление сложных сценариев | Техническое задание, список камер и СИЗ |
| 2. Сбор данных | Запись видео с 2–5 камер в разных условиях | 2000+ кадров с разметкой |
| 3. Дообучение | YOLOv8 с аугментацией, hard negative mining | Модель mAP > 0.85 |
| 4. Интеграция | Настройка трекера, API, дашборда | Система в эксплуатации |
| 5. Поддержка | Мониторинг, дообучение при смене условий | Гарантия 6 месяцев |
Сроки ориентировочно
| Масштаб | Срок |
|---|---|
| Детектор каски + жилета (2–4 камеры) | 2–4 недели |
| Полный PPE (6+ типов, 10+ камер) | 5–9 недель |
| С дашбордом и автоматическими актами | 7–12 недель |
Что входит в работу
- Дообученная модель детекции (YOLOv8) под ваши условия.
- REST API для интеграции с существующей системой видеонаблюдения.
- Веб-дашборд с графиками нарушений и compliance rate.
- Автоматические акты о нарушении (PDF/excel).
- Обучение сотрудников охраны труда работе с системой.
- Техническая поддержка на 3 месяца.
Типичные ошибки и их решения
| Проблема | Причина | Решение |
|---|---|---|
| Ложное срабатывание на тени | Недостаток отрицательных примеров | Hard negative mining |
| Пропуск каски при сильном дожде | Капли воды искажают форму | Добавить дождевые аугментации |
| Двойная фиксация нарушения | Дублирование треков | Настроить cooldown 30 кадров |
Чтобы оценить внедрение на вашем объекте, свяжитесь с нами — мы проведём аудит и подготовим предложение. Закажите пилотный проект на 2–4 камеры, чтобы убедиться в эффективности системы. Подробнее о Personal protective equipment — терминология и стандарты.







