Камеры

Камера превращает свет от сцены в двумерный массив пикселей. Для человека кадр сразу выглядит как куб, линия или дорожный знак. Программа получает только числа и должна шаг за шагом выделить полезный признак: цвет, границу, форму, движение или положение знакомого объекта.
Камера робота — это сенсор изображения. Объектив формирует изображение на светочувствительной матрице, драйвер передаёт кадры программе, а алгоритм преобразует пиксели в решение: например, «оранжевая метка находится левее центра».
Зачем это нужно
Дальномер сообщает, насколько близко препятствие, но обычно не показывает его цвет и рисунок. Камера даёт гораздо более богатые данные. С ней учебный робот может:
- следовать по цветной линии;
- находить метку или нужную деталь;
- оценивать смещение объекта относительно центра кадра;
- замечать изменение сцены;
- читать машинные маркеры после отдельной настройки алгоритма;
- передавать оператору изображение для наблюдения.
Цена такого богатства — объём данных и зависимость от условий. Один кадр содержит тысячи или миллионы пикселей. Освещение, выдержка, фокус, размытие и искажение объектива меняют числа даже тогда, когда сам объект остаётся на месте.
Главная идея
Работу камеры удобно разделить на цепочку:
свет сцены → оптика и матрица → кадр → обработка пикселей → признак → команда
Сенсор заканчивает работу на кадре. Названия объектов, их границы и управляющая команда появляются только после обработки.
| Уровень | Пример данных | Вопрос программы |
|---|---|---|
| поток | последовательность кадров и меток времени | пришёл ли новый кадр? |
| кадр | матрица пикселей | каковы размер и кодирование? |
| признаки | маска цвета, контуры, ключевые точки | где находится интересующая область? |
| решение | ошибка положения, класс, команда | как должен действовать робот? |
Это разделение помогает искать ошибку. Чёрный экран проверяют на уровне подключения и потока. Неправильный цвет — на уровне кодирования и освещения. Неверный поворот — на уровне координат и управляющей логики.
Из чего получается кадр
Объектив направляет свет на матрицу. Матрица состоит из светочувствительных элементов, а электронная схема считывает их сигналы. В обычном цветном изображении программа часто работает с тремя каналами, например красным, зелёным и синим. Однако порядок каналов зависит от формата и библиотеки: OpenCV традиционно представляет многие цветные кадры в порядке BGR.
Кадр имеет ширину, высоту и кодирование. В ROS 2 сообщение sensor_msgs/Image хранит число строк и столбцов, строку кодирования, длину строки в байтах и массив данных. Метка времени должна соответствовать моменту захвата кадра, а система координат — оптической системе камеры.
Пиксель задаёт место в двумерном кадре. Без дополнительных данных одна камера не сообщает прямую метрическую дальность до произвольного пикселя. Для расстояния нужны известный масштаб, геометрия сцены, движение, стереопара или камера глубины.
Подключение камеры
На учебных платформах чаще встречаются два пути подключения:
| Вариант | Физическое соединение | Программный путь | На что обратить внимание |
|---|---|---|---|
| USB-камера | USB | системный видеодрайвер, например V4L2 в Linux | узел /dev/videoX, его возможности, формат и пропускная способность |
| камерный модуль | CSI-2 и шлейф | драйвер платформы и камерный стек | ориентация шлейфа, совместимость модуля, питание |
| сетевой поток | Ethernet или Wi-Fi | URL и протокол потока | задержка, обрывы, сжатие, доступ |
| готовый видеофайл | файл на диске | декодер видео | это повторяемый тест, но не проверка реального сенсора |
Документация ядра Linux описывает V4L2-устройства захвата как узлы вида /dev/videoX; приложение может запросить возможности и формат, а затем получать кадры через чтение или потоковый ввод-вывод. Для камер Raspberry Pi библиотека Picamera2 предоставляет Python API поверх современного камерного стека libcamera и заменяет старую Picamera; устаревший стек из старых руководств не следует смешивать с новым.
Перед кодом проверьте физическую часть:
- Отключите питание перед установкой шлейфа, если этого требует руководство платы.
- Убедитесь, что камера закреплена и не смотрит в корпус робота.
- Проверьте, что операционная система видит устройство.
- Получите один тестовый кадр штатной утилитой.
- Только затем подключайте библиотеку компьютерного зрения.
Получение кадра в OpenCV
Класс cv.VideoCapture открывает устройство, видеофайл или поддерживаемый поток. Минимальный цикл на Python выглядит так:
import cv2 as cv
camera = cv.VideoCapture(0)
if not camera.isOpened():
raise RuntimeError("Камера не открылась")
ok, frame = camera.read()
camera.release()
if not ok or frame is None:
raise RuntimeError("Кадр не получен")
height, width = frame.shape[:2]
print(width, height)
Проверки isOpened() и результата read() отвечают на разные вопросы. Первая показывает, удалось ли открыть источник. Вторая — получен ли конкретный кадр. Поток может открыться, а позднее перестать отдавать данные.
Для движущегося робота цикл выполняется многократно. Каждый кадр должен иметь метку времени, особенно если изображение объединяется с IMU, колёсной одометрией или лидаром.
Координаты изображения
В изображении точку обычно записывают как (u, v) или (x, y): горизонтальная координата растёт вправо, вертикальная — вниз. Начало находится в левом верхнем углу. В ROS 2 Image это соглашение закреплено явно.
Если центр найденной области равен (cx, cy), а ширина кадра — W, горизонтальная ошибка может быть записана так:
error = cx - W / 2
error < 0— цель левее центра;error > 0— цель правее центра;error ≈ 0— цель около оптической оси.
Эта ошибка ещё не угол в градусах. Для перехода к геометрическим лучам нужны параметры камеры.
Калибровка камеры
Объектив искривляет проекцию, особенно по краям кадра. Калибровка оценивает внутренние параметры: фокусные длины в пикселях, положение главной точки и коэффициенты искажения. OpenCV использует снимки известного шаблона, например шахматной доски или сетки кругов, и затем может исправлять искажение.
| Параметр | Что описывает | Почему нужен |
|---|---|---|
fx, fy | масштаб проекции по двум осям | связать направление луча с координатой пикселя |
cx, cy | главную точку | определить оптический центр изображения |
| коэффициенты искажения | отклонение от идеальной модели | выпрямить геометрию кадра |
| внешнее преобразование | положение камеры относительно робота | перевести результат в систему шасси |
Калибровка одной камеры не делает её датчиком глубины. Она даёт геометрическую модель проекции, но расстояние до неизвестного объекта из одного кадра остаётся неоднозначным.
Базовая задача: выделить цвет

Для первого эксперимента полезно не распознавать «всё», а выделить один хорошо отличимый цвет. Поток обработки может быть таким:
- Получить кадр.
- Преобразовать цветовое пространство BGR в HSV.
- Оставить пиксели внутри выбранного диапазона функцией
inRange. - Найти связанную область или контур.
- Вычислить центр области.
- Сравнить его с центром кадра и выдать команду поворота.
import cv2 as cv
import numpy as np
frame = cv.imread("test-frame.png")
if frame is None:
raise RuntimeError("Тестовый кадр не найден")
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
lower = np.array([5, 120, 80], dtype=np.uint8)
upper = np.array([25, 255, 255], dtype=np.uint8)
mask = cv.inRange(hsv, lower, upper)
moments = cv.moments(mask, binaryImage=True)
if moments["m00"] > 0:
cx = moments["m10"] / moments["m00"]
error = cx - frame.shape[1] / 2
print(round(error, 1))
else:
print("Цель не найдена")
Числа диапазона здесь — только старт для контролируемого теста, а не универсальные настройки оранжевого цвета. Их нужно подобрать по кадрам именно своей камеры и затем проверить при изменении освещения.
Маска — изображение того же размера, где каждый пиксель отвечает на простой вопрос: принадлежит ли он выбранной области. Обычно интересующая область белая, остальные пиксели чёрные.
От изображения к движению
Рассмотрим робота, который поворачивается к цветному маркеру. Сама маска недостаточна: маленькое пятно шума тоже может пройти порог. Алгоритм вводит дополнительные проверки — минимальную площадь, допустимое положение и устойчивость в нескольких кадрах.
| Наблюдение | Возможная причина | Действие программы |
|---|---|---|
| крупная область слева | цель слева | плавно повернуть влево |
| крупная область справа | цель справа | плавно повернуть вправо |
| область около центра | цель выровнена | двигаться вперёд по отдельному правилу безопасности |
| нет подходящей области | цель вне кадра или условия изменились | искать цель или остановиться |
| множество мелких пятен | шум, блики, неверный порог | фильтровать по площади и проверить свет |
Команда «вперёд» не должна отменять проверку расстояния. Камера может видеть маркер за прозрачной перегородкой или не замечать низкое препятствие. В реальном роботе зрительный алгоритм работает вместе с датчиками безопасности.
Частые ошибки
Неверный индекс камеры. 0 — не обещание конкретного разъёма. В Linux номер /dev/videoX может зависеть от порядка обнаружения устройств. Сначала перечислите доступные источники.
Перепутанные каналы. Порог, рассчитанный для RGB, даст другой результат на BGR-кадре. Записывай формат в интерфейсе между узлами.
Игнорирование освещения. Автоэкспозиция и баланс белого изменяют пиксели. Проверяй диапазон на разных кадрах и сохраняй не только маску, но и исходное изображение для диагностики.
Тяжёлая обработка каждого пикселя. Уменьшение кадра или выделение области интереса снижает нагрузку, но меняет точность и координаты. Это инженерный компромисс, а не бесплатное ускорение.
Использование последнего кадра без времени. При задержке робот может реагировать на сцену, которой уже нет. Измеряй возраст кадра и время обработки.
Что запомнить про камеру
- Камера отдаёт кадры, а не готовые названия объектов.
- Размер, кодирование и метка времени — часть измерения.
- Пиксельные координаты двумерны; метрическая глубина из них напрямую не следует.
VideoCaptureнужно проверять и при открытии, и при чтении кадра.- Базовое зрение строится как цепочка простых стадий: кадр, преобразование, маска, признак, решение.
- Калибровка исправляет геометрию проекции, но не заменяет датчик расстояния.
- Любой алгоритм надо испытывать при разных условиях освещения и движения.
Практика
Задание 1. Паспорт кадра
Подключите доступную камеру или возьмите видеофайл. Запишите фактические ширину, высоту, число каналов, частоту получения кадров и средний интервал между ними. Отдельно отметьте, какой источник открылся по индексу 0.
Задание 2. Цветовая маска
Подготовьте три снимка одного цветного предмета: при ярком, слабом и боковом освещении. Подберите один диапазон HSV и сравните площадь маски на всех снимках. Ответа «правильный диапазон» нет — опишите способ проверки устойчивости.
Задание 3. Центр цели
Для найденной области вычислите error = cx - W / 2. Придумайте три зоны управления: поворот влево, движение прямо и поворот вправо. Выберите границы зон и объясните, как они зависят от разрешения кадра.
Задание 4. Диагностика задержки
Составьте план опыта, который отделит задержку получения кадра от времени его обработки. Какие метки времени и события вы запишете? Как поймёте, что робот реагирует на устаревшее изображение?
Проверьте себя
- Чем кадр отличается от распознанного объекта?
- Какие данные, кроме массива пикселей, нужны программе?
- Почему
isOpened()не заменяет проверку результатаread()? - Где находится начало координат изображения?
- Что показывает бинарная маска?
- Для чего нужны внутренние параметры камеры?
- Почему откалиброванная одиночная камера не выдаёт глубину каждого пикселя?
- Как изменение освещения влияет на цветовой порог?
Сначала ответьте без подсказки. Ответ можно считать полным, если вы:
- формулируете основную мысль своими словами;
- называете важные условия, ограничения или меры безопасности;
- для схемы, кода или расчёта показываете ход решения и ожидаемый результат.
Если один из пунктов объяснить не получается, найдите соответствующую главу статьи, перечитайте её и повторите ответ.
Словарь статьи
- Кадр — одно двумерное изображение из потока камеры.
- Пиксель — элемент изображения с числовыми значениями каналов.
- Канал — одна составляющая представления цвета или яркости.
- Разрешение — ширина и высота кадра в пикселях.
- Кодирование — соглашение о значении и порядке байтов и каналов.
- Экспозиция — количество света, учитываемое при получении кадра.
- Калибровка камеры — оценка параметров проекции и искажения объектива.
- Главная точка — проекция оптической оси на плоскость изображения в модели камеры.
- Маска — изображение выбора, отделяющее интересующие пиксели от остальных.
- Контур — граница связанной области на изображении.
- Область интереса — часть кадра, которую алгоритм обрабатывает отдельно.
Связанные темы
- Лидары — сканирование расстояний и карты препятствий.
- Камеры глубины — изображение, связанное с измеренной дальностью.
- IMU-модули — измерение движения и ориентации камеры на платформе.
- Фильтрация данных с датчиков — фильтрация, синхронизация и объединение потоков.
- Ограничения сложных сенсоров — свет, отражения, вибрации, частота и нагрузка.
Источники
- OpenCV.
cv::VideoCapture: https://docs.opencv.org/4.x/d8/dfe/classcv_1_1VideoCapture.html - OpenCV. Thresholding Operations using
inRange: https://docs.opencv.org/4.x/da/d97/tutorial_threshold_inRange.html - OpenCV. Camera Calibration: https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html
- Linux Kernel. Video Capture Interface (V4L2): https://docs.kernel.org/userspace-api/media/v4l/dev-capture.html
- ROS 2
sensor_msgs/Image: https://github.com/ros2/common_interfaces/blob/rolling/sensor_msgs/msg/Image.msg - ROS 2
sensor_msgs/CameraInfo: https://github.com/ros2/common_interfaces/blob/rolling/sensor_msgs/msg/CameraInfo.msg - Raspberry Pi. Picamera2: https://github.com/raspberrypi/picamera2