Система комп'ютерного зору для безпеки персоналу на виробництві

На виробництві з роботами-маніпуляторами, штампувальними пресами та високовольтним обладнанням кожен інцидент з персоналом — це ризик травми, зупинка лінії та штрафи. Стандартні системи відеоаналітики дають багато хибних спрацьовувань: тінь, проїжджаюча візок, відображення у склі — все це викликає х

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1302
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1267
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    714
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1006

На виробництві з роботами-маніпуляторами, штампувальними пресами та високовольтним обладнанням кожен інцидент з персоналом — це ризик травми, зупинка лінії та штрафи. Стандартні системи відеоаналітики дають багато хибних спрацьовувань: тінь, проїжджаюча візок, відображення у склі — все це викликає хибну тривогу. За даними статистики, понад 30% нещасних випадків на виробництві пов'язані з перебуванням людей у небезпечних зонах [ILO Safety Report]. Ми розробляємо AI-системи комп'ютерного зору, які відстежують не просто перетин bbox з зоною, а геопросторове положення ключових точок тіла — ніг та стегон. Це знижує false alarm rate до 5% та дозволяє реагувати за 100 мс. Система працює під ключ: від калібрування камери до інтеграції з PLC/SCADA та сертифікації SIL. Ми гарантуємо точність відповідно до сертифіката SIL 2 та надаємо підтримку 24/7.

Проблема: стандартна детекція bbox не підходить

Стандартна помилка — детектуємо людину та перевіряємо її bounding box на перетин з polygon зони. Проблема: людина стоїть біля межі зони, bbox перетинається з зоною на 10% — тривога? Правильно: відстежуємо конкретні точки тіла (ноги) в зоні, а не весь bbox. Використовуємо pose estimation (YOLOv8-pose) та Shapely для точної перевірки.

import cv2 import numpy as np from shapely.geometry import Point, Polygon from ultralytics import YOLO from collections import defaultdict class DangerZoneMonitor: """ Моніторинг небезпечних зон через: 1. Pose estimation → ключові точки (ноги, руки) 2. Перевірка точок у зонах через Shapely 3. Трекінг персон для зниження false positives """ def __init__( self, model_path: str = 'yolov8m-pose.pt', danger_zones: list[dict] = None, # Список зон: [{'id': 'zone_1', 'polygon': [(x1,y1), ...], 'severity': 'critical'}] min_frames_before_alert: int = 3 # 3 кадри підряд = справжнє порушення ): self.model = YOLO(model_path) self.zones = [ { 'id': z['id'], 'polygon': Polygon(z['polygon']), 'severity': z.get('severity', 'high'), 'check_points': z.get('check_points', 'feet') # 'feet' | 'any' | 'center' } for z in (danger_zones or []) ] self.min_frames = min_frames_before_alert self.violation_counters: dict = defaultdict(int) # person_track_id → consecutive frames def process_frame( self, frame: np.ndarray ) -> dict: """ Повертає {'violations': [...], 'annotated_frame': np.ndarray} """ # YOLOv8-pose: детекція + позиція + трекінг results = self.model.track( frame, persist=True, # ByteTrack трекінг conf=0.4, verbose=False )[0] active_track_ids = set() violations = [] if results.keypoints is not None and results.boxes.id is not None: keypoints = results.keypoints.xy.cpu().numpy() # (N, 17, 2) confidences = results.keypoints.conf.cpu().numpy() # (N, 17) track_ids = results.boxes.id.cpu().numpy().astype(int) for i, (kpts, confs, track_id) in enumerate( zip(keypoints, confidences, track_ids) ): active_track_ids.add(track_id) check_points = self._get_check_points(kpts, confs) for zone in self.zones: in_zone = any( confs[idx] > 0.5 and zone['polygon'].contains(Point(kpts[idx])) for idx in check_points ) if in_zone: self.violation_counters[track_id] += 1 if self.violation_counters[track_id] >= self.min_frames: violations.append({ 'track_id': int(track_id), 'zone_id': zone['id'], 'severity': zone['severity'], 'consecutive_frames': self.violation_counters[track_id], 'person_bbox': results.boxes.xyxy[i].cpu().numpy().tolist() }) else: self.violation_counters[track_id] = 0 # Скидаємо лічильники для зниклих персон for track_id in list(self.violation_counters.keys()): if track_id not in active_track_ids: del self.violation_counters[track_id] annotated = self._annotate_frame(frame, violations, results) return {'violations': violations, 'annotated_frame': annotated} def _get_check_points( self, keypoints: np.ndarray, confidences: np.ndarray ) -> list[int]: """ COCO keypoints: 0=ніс, 1-4=очі/вуха, 5-6=плечі, 7-8=лікті, 9-10=зап'ястя, 11-12=стегна, 13-14=коліна, 15-16=щиколотки Ноги = індекси 15, 16 (щиколотки) """ feet_indices = [15, 16] # Якщо ноги не детектовані → використовуємо стегна як fallback feet_detected = any(confidences[i] > 0.5 for i in feet_indices) if feet_detected: return feet_indices return [11, 12] # стегна як запасні точки def _annotate_frame( self, frame: np.ndarray, violations: list, results ) -> np.ndarray: annotated = frame.copy() # Малюємо зони for zone in self.zones: pts = np.array(list(zone['polygon'].exterior.coords), dtype=np.int32) color = (0, 0, 255) if any( v['zone_id'] == zone['id'] for v in violations ) else (0, 255, 0) cv2.polylines(annotated, [pts], True, color, 2) cv2.fillPoly( annotated, [pts], tuple(int(c * 0.2) for c in color) ) # Малюємо порушників for v in violations: bbox = list(map(int, v['person_bbox'])) cv2.rectangle( annotated, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 0, 255), 3 ) cv2.putText( annotated, f"VIOLATION: {v['zone_id']}", (bbox[0], bbox[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2 ) return annotated 

Чому геопросторова перевірка точніша за детекцію bbox?

При детекції bbox людина може стояти впритул до зони, але її ноги вже всередині — система зобов'язана зреагувати. Ми використовуємо pose estimation і перевіряємо попадання щиколоток (або стегон як fallback) в polygon зони. Це дає Recall по вторгненнях >95% при False Alarm Rate <5%. Для зон з критичною небезпекою (преси, роботи) налаштовуємо пороги до 99% recall ціною невеликого зростання хибних спрацьовувань.

Як інтегрувати систему з існуючим PLC/SCADA?

Система підтримує Modbus TCP, OPC-UA та GPIO. При виявленні порушення надсилаємо сигнал Emergency Stop за 50–100 мс. Для критичних застосувань передбачений hardware override — реле, що розмикає ланцюг безпеки. Інтеграція займає 2–3 тижні після калібрування камер.

Калібрування камери для точних координат

Якщо зони задані в метрах (вимоги охорони праці), необхідна перспективна трансформація. Наводимо код калібратора.

import cv2 import numpy as np class ZoneCameraCalibrator: """ Перспективна трансформація: піксельні координати → реальні (метри). Необхідна для зон, заданих в метрах (вимоги ОП). """ def __init__( self, reference_points_px: list, # 4 точки в пікселях (на зображенні) reference_points_world: list # 4 точки в метрах (реальні координати) ): src = np.float32(reference_points_px) dst = np.float32(reference_points_world) self.H = cv2.getPerspectiveTransform(src, dst) def pixel_to_world(self, px: tuple) -> tuple: """(x_px, y_px) → (x_meters, y_meters)""" pt = np.float32([[[px[0], px[1]]]]) world = cv2.perspectiveTransform(pt, self.H) return float(world[0][0][0]), float(world[0][0][1]) def world_to_pixel(self, world: tuple) -> tuple: """(x_meters, y_meters) → (x_px, y_px)""" H_inv = np.linalg.inv(self.H) pt = np.float32([[[world[0], world[1]]]]) px = cv2.perspectiveTransform(pt, H_inv) return int(px[0][0][0]), int(px[0][0][1]) 

Latency та параметри системи

Параметр Рекомендація Чому
Роздільна здатність інференсу 640×640 Баланс швидкість/точність для людей
FPS камери 15–25 fps Рух людини: 1м/с → 4–7 см/кадр
min_frames_before_alert 3–5 кадрів Зниження хибних тривог
Latency вимога < 100ms Час реакції системи безпеки
GPU RTX 3060 12GB 8–12 камер одночасно при 640px

Порівняння моделей: YOLOv8 vs RT-DETR

YOLOv8 виграє в швидкості у 2 рази (35–45 FPS проти 18–25 FPS на RTX 3060). RT-DETR точніший (AP 0.94 vs 0.90), але швидкість критична для багатьох камер. Для однієї-двох камер вибираємо RT-DETR. В обох випадках inference latency нижче 30 мс на GPU. YOLOv8-pose також дає ключові точки, що критично для нашої геопросторової перевірки.

Що входить в роботу

Обстеження об'єктаРозстановка камер, визначення небезпечних зон, збір референсних кадрів.
Калібрування камерПрив'язка піксельних координат до реальних метрів.
Навчання/до навчання моделіАдаптація під специфіку виробництва (пил, освітлення).
Розробка бекендуFastAPI, інтеграція з PLC через Modbus/OPC-UA, логування порушень.
Веб-дашбордРеальний час, алерти, історія, статистика.
ТестуванняA/B-тест на одній камері, вимірювання Recall та False Alarm Rate.
Документація та навчання персоналуПовна технічна документація та тренінг операторів.
Пост-релізна підтримка6 місяців моніторингу та доопрацювань.

Строки

Задача Строк
Детектор проникнення в зону (1–3 камери) 3–5 тижнів
Масштабована система (10+ камер, дашборд) 7–12 тижнів
Сертифікація як система безпеки (SIL) 20+ тижнів

Наш досвід

Більше 7 років розробляємо системи комп'ютерного зору для промисловості. Реалізували 50+ проєктів з безпеки персоналу: від детекції в зоні преса до моніторингу периметра складу. Середнє зниження хибних тривог — 80% після впровадження нашої геопросторової логіки. Ми маємо досвід сертифікації SIL 2 та гарантію на систему 12 місяців. Вартість пілотного проєкту стартує від 15 000$. Зв'яжіться з нами для безкоштовної оцінки вашого проєкту. Замовте пілотне впровадження на одній камері — результат за 2 тижні.