Разработка системы измерения объектов по изображению/видео

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

Разработка системы измерения объектов по изображению или видео — задача, которую мы решаем с помощью компьютерного зрения. На производстве деталь только что вышла из станка, горячая (80°C), контактный замер штангенциркулем деформирует поверхность, давая погрешность до 0.5 мм. Бесконтактное измерение через камеру: снимок за 50 мс, точность ±0.1 мм, данные сразу в SCADA. Никакого риска ожога или остановки конвейера.

Задачи, которые решает система

Контроль качества на производстве. Деталь только что вышла из станка — отклонение от чертежа фиксируется мгновенно. Система замеряет длину, ширину, диаметр, углы и площадь контура за 50 мс. Выход за допуск — сигнал оператору или стоп линии.

Полевые измерения без доступа к объекту. Нужно узнать ширину трещины в стене или диаметр трубы на высоте? Размещаете ArUco маркер рядом, делаете снимок — через секунду размеры известны. Лестницы и линейки не нужны.

Логистика и склад. Габариты коробок на ленте транспортера измеряются в движении. Система автоматически присваивает каждой единице длину, ширину, высоту — для оптимизации загрузки контейнера.

Как обеспечить точность до миллиметра?

Ключевой параметр — масштаб. Используем три метода:

  1. Калиброванная камера — один раз фотографируете калибровочную пластину с рабочего расстояния, вычисляем pixels_per_mm. Точность ±0.1 мм. Идеально для статичных конвейеров.

  2. ArUco маркер в кадре — маркер известного размера (например, 50 мм) лежит рядом с объектом. Система определяет маркер, вычисляет масштаб, затем измеряет объект. Точность ±1–5 мм, подходит для полевых условий.

  3. Стереопара — две камеры, разнесённые на 10 см, дают 3D-облако точек. Из него извлекаются габаритные размеры, глубина, объём. Точность ±0.5–2 мм на объектах до 1 м.

Выбор метода зависит от задачи. Для конвейера с фиксированным положением камеры — калибровка. Для мобильного планшета — ArUco. Для крупных объектов (мебель, паллеты) — стерео или LiDAR+RGB.

Как выбрать метод измерения?

— Если объект движется на конвейере с постоянной скоростью и камера закреплена — выбирайте калиброванную камеру. Максимальная точность ±0.1 мм и время измерения 50 мс.

— Если вы на складе или в поле — используйте ArUco маркер. Распечатайте маркер 5×5 см, наклейте на твёрдую основу и кладите рядом с объектом. Система автоматически определит масштаб.

— Если нужно измерить объём или глубину — ставьте стереопару. Две камеры с базисом 10 см построят 3D-модель и выдадут габариты в миллиметрах.

Пошаговая инструкция: как система измеряет объект

  1. Захват изображения. Камера делает снимок (или кадр из видео). При настройке указываем разрешение и частоту.
  2. Определение масштаба. Система находит калибровочный объект или ArUco маркер, вычисляет pixels_per_mm.
  3. Сегментация объекта. Используем пороговую обработку (Otsu) или нейросеть для сложных контуров.
  4. Извлечение размеров. По контуру вычисляем bounding box, минимальный прямоугольник, периметр, площадь.
  5. Конвертация в миллиметры. Умножаем пиксельные значения на pixels_per_mm.
  6. Вывод результата. Отправляем данные в JSON, БД или на экран оператора.

Что входит в работу

  • Анализ задачи: пришлите фото/видео объекта с описанием условий съёмки (дальность, освещение, движение). Мы подбираем метод и готовим смету за 1 день.
  • Прототип: за 3–5 дней пишем демо-версию под ваш сценарий. Вы тестируете на реальных данных.
  • Разработка: реализуем алгоритмы сегментации, калибровки, измерения. Стек: OpenCV, PyTorch (если нужна нейросеть для сложных контуров), Docker, FastAPI.
  • Интеграция: встраиваем модуль в вашу PLC/SCADA, добавляем REST API, MQTT, Modbus.
  • Документация и обучение: передаём код, описание API, инструкции для операторов.
  • Поддержка: 3 месяца бесплатного сопровождения, далее — по договору.

Сроки ориентировочно

Задача Срок
2D-измерение на конвейере 2–4 недели
Система с ArUco для полевого применения 3–5 недель
3D-стерео система 6–10 недель

Стоимость рассчитывается индивидуально и зависит от сложности сегментации, количества камер, необходимости нейросетей. Напишите нам — за 1 день получите предварительную оценку.

Почему выбирают нас?

Опыт более 5 лет в промышленном CV. Реализовали 50+ проектов для машиностроения, логистики, медицины. Гарантия точности: фиксируем метрологические характеристики в договоре. Всегда предоставляем отчёт по валидации. Процессы разработки стандартизированы по ISO 9001. Сравнение с аналогами: наше решение дешевле западных Halcon/Matrox в 2–3 раза при сопоставимой точности, а срок внедрения в 1.5 раза короче.

Наши заказчики экономят до $18k–26k в год на контроле качества. Например, один клиент сократил время инспекции на 80%, что эквивалентно экономии около $14k–20k в год. Получите консультацию инженера с пятилетним опытом в CV — свяжитесь с нами.

Методы масштабирования

Метод 1: Калиброванная камера

Один раз фотографируем объект известного размера (калибровочная пластина) с рабочего расстояния, вычисляем коэффициент pixels_per_mm:

import cv2
import numpy as np

class CalibratedMeasurement:
    def __init__(self, pixels_per_mm: float, camera_matrix: np.ndarray = None, dist_coefficients: np.ndarray = None):
        self.ppm = pixels_per_mm
        self.camera_matrix = camera_matrix
        self.dist_coefficients = dist_coefficients

    def calibrate_from_reference(self, image: np.ndarray, known_width_mm: float) -> float:
        """Калибровка по объекту известной ширины"""
        # Предполагаем что объект уже выровнен и занимает ~80% ширины
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        main = max(contours, key=cv2.contourArea)
        x, y, w, h = cv2.boundingRect(main)
        self.ppm = w / known_width_mm
        return self.ppm

    def measure_contour(self, image: np.ndarray) -> dict:
        """Измерение основных параметров объекта"""
        if self.camera_matrix is not None:
            # Исправление дисторсии линзы
            image = cv2.undistort(image, self.camera_matrix, self.dist_coefficients)
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        if not contours:
            return {'measured': False}
        c = max(contours, key=cv2.contourArea)
        # Bounding rectangle
        x, y, w, h = cv2.boundingRect(c)
        # Минимальный описывающий прямоугольник (с вращением)
        rect = cv2.minAreaRect(c)
        (cx, cy), (rw, rh), angle = rect
        min_side = min(rw, rh)
        max_side = max(rw, rh)
        # Периметр через arc length
        perimeter_px = cv2.arcLength(c, True)
        # Площадь
        area_px = cv2.contourArea(c)
        return {
            'width_mm': round(w / self.ppm, 3),
            'height_mm': round(h / self.ppm, 3),
            'length_mm': round(max_side / self.ppm, 3),
            'width_min_mm': round(min_side / self.ppm, 3),
            'angle_deg': round(angle, 2),
            'perimeter_mm': round(perimeter_px / self.ppm, 3),
            'area_mm2': round(area_px / self.ppm**2, 3),
            'center': (round(cx / self.ppm, 2), round(cy / self.ppm, 2))
        }"}

Метод 2: Референсный объект в кадре (ArUco маркеры)

import cv2.aruco as aruco

def measure_with_aruco(image: np.ndarray, marker_size_mm: float = 50.0) -> dict:
    """Измерение с ArUco маркером как референсом"""
    aruco_dict = aruco.getPredefinedDictionary(aruco.DICT_4X4_250)
    detector = aruco.ArucoDetector(aruco_dict)
    corners, ids, _ = detector.detectMarkers(image)
    if ids is None:
        return {'error': 'no_aruco_marker_found'}
    # Вычисляем pixels_per_mm из маркера
    marker_corners = corners[0][0]
    marker_width_px = np.linalg.norm(marker_corners[0] - marker_corners[1])
    ppm = marker_width_px / marker_size_mm
    # Дальше стандартное измерение
    measurer = CalibratedMeasurement(pixels_per_mm=ppm)
    return measurer.measure_contour(image)

Измерение в 3D через стереопару

class StereoCameraMeasurement:
    def __init__(self, stereo_calibration: dict):
        self.Q = stereo_calibration['Q']  # disparity-to-depth матрица
        self.baseline_mm = stereo_calibration['baseline_mm']
        self.focal_length_px = stereo_calibration['focal_length_px']

    def measure_3d(self, left_img: np.ndarray, right_img: np.ndarray) -> dict:
        # Stereo matching
        stereo = cv2.StereoSGBM_create(
            minDisparity=0,
            numDisparities=96,
            blockSize=11,
            P1=8 * 3 * 11**2,
            P2=32 * 3 * 11**2,
            disp12MaxDiff=1,
            uniquenessRatio=10,
            speckleWindowSize=100,
            speckleRange=32
        )
        disparity = stereo.compute(
            cv2.cvtColor(left_img, cv2.COLOR_BGR2GRAY),
            cv2.cvtColor(right_img, cv2.COLOR_BGR2GRAY)
        ).astype(np.float32) / 16.0

        # Конвертация диспаретности в 3D облако точек
        points_3d = cv2.reprojectImageTo3D(disparity, self.Q)
        return self._extract_dimensions_3d(points_3d)

Точность и применения

Метод Диапазон Точность Применение
2D с калибровкой (фиксированное расстояние) 1–500 мм ±0.1–0.5 мм Конвейер, QC
ArUco референс 10–2000 мм ±1–5 мм Полевые измерения
Стерео (10 cm базис) 50–1000 мм ±0.5–2 мм 3D измерение
LiDAR + RGB 100–5000 мм ±1–3 мм Крупные объекты

По данным исследования NIST, бесконтактное измерение снижает погрешность на 40%. Готовы обсудить вашу задачу. Напишите нам — оценим проект за 1 день. Получите консультацию инженера.

Направления AI-разработки

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139