Здесь вы узнаете, что такое маркеры ArUco и зачем они нужны в задачах дополненной реальности с использованием OpenCV.
В задачах дополненной реальности маркеры ArUco некоторое время применяли для оценке позиционирования и калибровки камеры. Давайте узнаем об это побольше.
Что есть маркеры ArUco?
Первое сообщение о маркерах ArUco появилось в 2014 году в работе S.Garrido-Jurado с соавторами
Маркер ArUco — это фидуциальный маркер, который размещается на изображаемом объекте или сцене. Он представляет собой чёрный квадрат с ярко выраженными границами, внутри которого располагается белый узор, однозначно его идентифицирующий. Черная граница облегчает его обнаружение. Маркеры могут быть созданы разных размеров. Размер выбирается в зависимости от размера объекта или сцены для надёжного обнаружения. Если очень маленькие маркеры не обнаруживаются, то простое увеличение их размера позволит их обнаружить.
Идея в заключается том, что вы печатаете маркеры или наносите их на реальные объекты. Можно сделать фотографию реального мира и на фото однозначно обнаружить эти маркеры.
Если вы новичок, то можете задуматься, а зачем все это? Посмотрим на пару примеров полезности.
Здесь мы поместили маркеры по углам рамки рисунка. Когда мы однозначно идентифицируем маркеры, то можем заменить изображение внутри рамки произвольным видео или другой картинкой. Новая картика будет иметь правильное искажение перспективы, когда мы станем перемещать камеру.
В приложениях робототехники можно поместить маркеры вдоль пути складского робота, оборудованного камерой. Когда камера, установленная на роботе, найдет один из маркеров, то можно точно определить его местоположение на складе, поскольку каждый маркер имеет уникальный идентификатор и мы точно знаем, где какой маркер стоит.
Создание маркеров ArUco в OpenCV
Используя OpenCV можно легко генерировать эти маркеры. Модуль aruco
в OpenCV имеет в общей сложности aruco
в Python.
Нам нужно будет использовать модуль aruco
в коде.
Вызов функции getPredefinedDictionary
, которая загружает словарь из 250 маркеров, где каждый маркер содержит шаблон 6×6 бит показан ниже.
import cv2 as cv import numpy as np # Загрузить предопределенный словарь dictionary = cv.aruco.Dictionary_get(cv.aruco.DICT_6X6_250) # Сгенерировать маркер markerImage = np.zeros((200, 200), dtype=np.uint8) markerImage = cv.aruco.drawMarker(dictionary, 33, 200, markerImage, 1); cv.imwrite("marker33.png", markerImage);
Приведенная выше функция drawMarker
позволяет выбрать маркер с заданным идентификатором (второй параметр – 33) из набора 250 маркеров, имеющих идентификаторы от 0 до 249. Третий параметр функции drawMarker
определяет размер сгенерированного маркера. В приведенном выше примере он будет генерировать изображение с размером 200×200 пикселей. Четвертый параметр представляет объект, в котором будет храниться сгенерированный маркер (markerImage
). Наконец, пятый параметр является параметром толщины и решает, сколько блоков должно быть добавлено в качестве границы сгенерированного двоичного шаблона. В приведенном выше примере вокруг сгенерированного шаблона размером 6×6 будет добавлена граница шириной 1 бит, что задает размер блока 7×7 бит в изображении размером 200×200 пикселей. Сгенерированный с помощью указанного выше кода маркер будет выглядеть так:
Для большинства приложений необходимо создавать несколько маркеров и размещать их в сцене.
Обнаружение маркеров Aruco
После размещения маркеров ArUco в сцене их надо обнаружить и использовать для дальнейшей обработки. Ниже показано, как найти маркеры.
# Загрузить словарь, который использовался для создания маркеров. dictionary = cv.aruco.Dictionary_get(cv.aruco.DICT_6X6_250) # Инициализировать параметры детектора, используя значения по умолчанию parameters = cv.aruco.DetectorParameters_create() # Обнаружение маркеров на изображении markerCorners, markerIds, rejectedCandidates = cv.aruco.detectMarkers(frame, dictionary, parameters=parameters)
Мы начнем с загрузки того же словаря, который мы использовали для создания маркеров.
Начальный набор параметров определяется с помощью функции cv.aruco.DetectorParameters_create()
. OpenCV позволяет нам изменять несколько параметров в процессе обнаружения. Список параметров, которые могут быть скорректированы, включая адаптивные пороговые значения, можно найти
Для каждого успешно обнаруженного маркера, вычисляются четыре угловые точки в следующем порядке верхняя левая, верхняя правая, нижняя правая и нижняя левая, по часовой стрелке, начиная с верхней левой. Именно в таком порядке они хранятся в массиве Numpyએ.
Функция detectMarkers
используется для обнаружения и определения местоположения углов маркеров. Первый параметр — это изображение сцены с маркерами. Второй параметр — словарь, используемый для генерации маркеров. Успешно обнаруженные маркеры будут сохранены, в markerCorners
, а их идентификаторы в markerIds
. Объект DetectorParameters
, инициализированный ранее, также передается в качестве параметра. Наконец, отклоненные кандидаты на маркеры сохраняются внутри rejectedCandidates
.
Для более надёжного обнаружения маркеров при их размещении в сцене рекомендуется формировать некоторую белую границу вокруг черной границы маркера.
Приложение дополненной реальности
Маркеры ArUco изначально разрабатывались для решения проблемы оценки ориентации камеры при использовании в различных приложениях, включая приложения дополненной реальности. OpenCV подробно описывает процесс оценки ориентации в своей
Здесь мы будем использовать их для приложения дополненной реальности, которое позволяет нам накладывать любую новую картинку или видео на существующее изображение. Мы выбираем сцену Дом с большой картиной и мы хотим заменить картину на новую и посмотреть, как она будет выглядеть на стене. Затем мы пытаемся вставить видеофильм вместо старой картины. Для этого мы генерируем, вырезаем и вставляем большие маркеры aruco
в углы области изображения, как показано на рисунке ниже, а затем снимаем видео. Захваченное видео находится в левой части видео в верхней части блога. Затем мы обрабатываем каждый кадр видео индивидуально по порядку.
Для каждого изображения сначала определяются маркеры. На рисунке ниже показаны обнаруженные маркеры, нарисованные зеленым цветом. Первая точка обозначена небольшим красным кружком. Вторая, третья и четвертая точки могут быть найдены на пересечении границы маркера по часовой стрелке.
Четыре соответствующих набора точек на входном изображении и новое изображение сцены используются для вычисления гомографии. Гомографияએ. Что это? О том, что такое гомографию можно прочитать
В нашем случае матрица гомографии используется для деформации нового изображения сцены в четырехугольник, определяемый маркерами в нашем захваченном изображении. Посмотрите, как это делается.
# Рассчитать гомографию h, status = cv.findHomography(pts_src, pts_dst) # Деформация исходного изображения к месту назначения на основе гомографии warped_image = cv.warpPerspective(im_src, h, (frame.shape[1],frame.shape[0])) # Подготовьте маску, представляющую область для копирования из деформированного изображения в исходный кадр. mask = np.zeros([frame.shape[0], frame.shape[1]], dtype=np.uint8); cv.fillConvexPoly(mask, np.int32([pts_dst_m]), (255, 255, 255), cv.LINE_AA); # Размыть маску, чтобы не копировать граничные эффекты из деформации element = cv.getStructuringElement(cv.MORPH_RECT, (3,3)); mask = cv.erode(mask, element, iterations=3); # Скопируйте маску на 3 канала. warped_image = warped_image.astype(float) mask3 = np.zeros_like(warped_image) for i in range(0, 3): mask3[:,:,i] = mask/255 # Скопируйте искаженное изображение в маске в исходный кадр в области маски. warped_image_masked = cv.multiply(warped_image, mask3) frame_masked = cv.multiply(frame.astype(float), 1-mask3) im_out = cv.add(warped_image_masked, frame_masked)
Мы используем новые угловые точки изображения сцены в качестве исходных точек (pts_src) и соответствующие угловые точки изображения внутри рамки изображения в нашем захваченном изображении в качестве точек назначения (dst_src) , Функция OpenCV findHomography
вычисляет функцию гомографии h между исходной и целевой точками. Матрица гомографии затем используется для деформации нового изображения, чтобы поместиться в целевой кадр. Деформированное изображение маскируется и копируется в целевой кадр. В случае видео этот процесс повторяется на каждом кадре.
Рекомендации
Pixabay Images/Videos:
По мотивам
Дополненная реальность с маркерами ArUco в OpenCV, опубликовано К ВВ, лицензия — Creative Commons Attribution-NonCommercial 4.0 International.
Респект и уважуха