К сожалению, документация не всегда четко описывает форму ввода в Python, а undistortPoints()
еще даже не имеет документации по Python.
Входные точки должны быть массивом формы (n_points, 1, n_dimensions)
. Итак, если у вас есть 2D-координаты, они должны быть в форме (n_points, 1, 2)
. Или для 3D-координат они должны быть в форме (n_points, 1, 3)
. Это верно для большинства функций OpenCV. Насколько мне известно, этот формат будет работать для всех функций OpenCV, в то время как некоторые функции OpenCV также будут принимать точки в форме (n_points, n_dimensions)
. Я считаю, что лучше просто сохранять все последовательно и в формате (n_points, 1, n_dimensions)
.
Чтобы было ясно, это означает, что массив из четырех 32-битных 2D-точек с плавающей запятой будет выглядеть так:
points = np.array([[[x1, y1]], [[x2, y2]], [[x3, y3]], [[x4, y4]]], dtype=np.float32)
Если у вас есть массив формы (n_points, n_dimensions)
, вы можете расширить его с помощью np.newaxis
:
>>> points = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
>>> points.shape
(4, 2)
>>> points = points[:, np.newaxis, :]
>>> points.shape
(4, 1, 2)
или с np.expand_dims()
:
>>> points = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
>>> points.shape
(4, 2)
>>> points = np.expand_dims(points, 1)
>>> points.shape
(4, 1, 2)
или с различным порядком np.transpose()
в зависимости от порядка ваших измерений. Например, если ваша фигура (1, n_points, n_dimensions)
, то вы хотите поменять местами ось 0 с осью 1, чтобы получить (n_points, 1, n_dimensions)
, поэтому points = np.transpose(points, (1, 0, 2))
изменит оси, поставив сначала ось 1, затем ось 0, затем ось 2, чтобы новая форма была правильной.
Если вы думаете, что это странный формат для точек, это если вы рассматриваете только список точек, но разумно, если вы думаете о точках как о координатах изображения. Если у вас есть изображение, то координаты каждой точки изображения определяются парой (x, y)
, например:
(0, 0) (1, 0) (2, 0) ...
(0, 1) (1, 1) (2, 1) ...
(0, 2) (1, 2) (2, 2) ...
...
Здесь имеет смысл поместить каждую координату в отдельный канал двухканального массива, чтобы получить один 2D-массив x-координат и один 2D-массив y-координат, например:
Канал 0 (х-координаты):
0 1 2 ...
0 1 2 ...
0 1 2 ...
...
Канал 1 (координаты Y):
0 0 0 ...
1 1 1 ...
2 2 2 ...
...
Вот почему каждая координата находится на отдельном канале.
Некоторые другие функции OpenCV, для которых требуется этот формат, включают cv2.transform()
и cv2.perspectiveTransform()
, о которых я уже отвечал на идентичные вопросы ранее, здесь и здесь соответственно.
person
alkasm
schedule
21.11.2017
[[x1, y1], [x2, y2], ...]
они должны быть на один уровень глубже, например[[[x1, y1]], [[x2, y2]], ...]
. Также убедитесь, что точки являются 32-битными или 64-битными числами с плавающей запятой, поэтому в целом массивы точек должны выглядеть какnp.array([[[x1, y1]], [[x2, y2]], ...], dtype=np.float32)
. Если это решит, я напишу это как ответ. - person alkasm   schedule 21.11.2017[[x1, y1], [x2, y2], ...]
. Как вы и предложили, сейчас пытаюсь добавить еще одно измерение командойcamera_points = np.array([camera_points], dtype=np.float32)
, но вместо[[[x1, y1]], [[x2, y2]], ...]
получаю[[[x1, y1], [x2, y2], ...]]
. Не могли бы вы подсказать мне, как это сделать правильно, чтобы я мог проверить? - person Shubs   schedule 21.11.2017points = points.transpose(1,0,2)
должно помочь (это переворачивает оси 0 и 1). - person alkasm   schedule 21.11.2017