Динамическая калибровка камеры OpenCV python3
Я планирую сделать роботизированную руку. У меня есть камера, установленная на руке. Я использую Opencv с python3, чтобы сделать IP.
Я хочу, чтобы рука обнаружила точку на земле и сервоприводы двигались соответственно. Я завершил часть обнаружения и расчета мировых координат. Также требуется обратная кинематика.
Проблема здесь в том, что я откалибровал камеру для определенной высоты (20 см). Итак, правильные мировые координаты принимаются только на высоте 20 см. Я хочу, чтобы камера продолжала корректировать показания каждые 2 секунды, когда она движется к земле (вниз).
Есть ли способ, которым я могу выполнить калибровку динамически и дать динамические координаты моей руке? Я не знаю, правильный ли это подход. Если есть другой способ сделать это, пожалуйста, помогите.
1 ответ
Я предполагаю, что вы используете undistort
функция, чтобы сначала не искажать изображение, а затем использовать вектор вращения (rcvt
) и поступательный вектор (tvct
) вместе с distortCoeffs
чтобы получить мировые координаты. Правильные координаты получаются только на этой конкретной высоте, потому что rvct
а также tvct
будет меняться в зависимости от размера квадрата (шахматной доски), используемого для калибровки.
Разумный способ преодолеть это - легко устранить вектор вращения и вектор перемещения.
Так как константы калибровки камеры остаются неизменными на любой высоте / повороте, это можно использовать в этом. Кроме того, вместо калибровки каждые 2 секунды (что потребляет слишком много ресурсов ЦП), напрямую используйте метод ниже, чтобы получить значения!
Скажем (img_x, img_y)
координата изображения, которую нужно преобразовать в мировую координату (world_x, world_y)
а также cameraMatrix
это матрица вашей камеры. Для этого метода вам нужно знать distance_cam
перпендикулярное расстояние вашего объекта от камеры.
Используя python и opencv, используйте следующий код:
import numpy as np
from numpy.linalg import inv
img_x, img_y = 20, 30 # your image coordinates go here
world_coord = np.array([[img_x], [img_y], [1]]) # create a 3x1 matrix
world_coord = inv(cameraMatrix) * world_coord # use formula cameraMatrix^(-1)*coordinates
world_coord = world_coord * distance_cam
world_x = world_coord[0][0]
world_y = world_coord[1][1]
print(world_x, world_y)
Сначала мы можем не осознавать, что единицы измерения в мировых координатах не имеют значения. После умножения на обратную матрицу камеры вы определили отношение x/z, которое не имеет единиц измерения. Итак, вы можете выбрать distance_cam
в любой единице, и конечный результат будет в единицах distance_cam
то есть если distance_cam
был в mm
, затем world_x, world_y
также будет в mm
,