Проблема с получением cv.transform для работы
Я хотел бы использовать ту же аффинную матрицу M в некоторых отдельных точках (x,y), что и в изображениях с cv2.warpAffine. Кажется, cv2.transform - это то, что нужно. Когда я пытаюсь отправить матрицу очков Nx2, я получаю отрицание (
src = np.array([
[x1,y1],[x2,y2],[x3,y3],[x4,y4]], dtype = "float32")
print('source shape '+str(src.shape))
dst=cv2.transform(src,M)
cv2.error: /home/jeremy/sw/opencv-3.1.0/modules/core/src/matmul.cpp:1947: error: (-215) scn == m.cols || scn + 1 == m.cols in function transform
Я могу получить преобразование, которое я хочу, просто используя арифметику NumPy:
dst = np.dot(src,M[:,0:2]) +M[:,2]
print('dest:{}'.format(dst))
Но хотел бы понять, что происходит. Документы говорят, что cv2.transform хочет количество каналов, равное количеству столбцов в M, но я не ясно, какими будут каналы - возможно, канал 'x' и канал 'y', но тогда будет третий и что означают разные строки?
2 ответа
OpenCV на Python часто хочет очки в форме
np.array([ [[x1, y1]], ..., [[xn, yn]] ])
Это не ясно в документации для cv2.transform()
но более ясно в документации для других функций, которые используют точки, такие как cv2.perspectiveTransform()
где они упоминают координаты, чтобы быть на отдельных каналах:
src - входной двухканальный или трехканальный массив с плавающей точкой
Преобразования также можно использовать в 3D (используя 4x4
матрица преобразования перспективы), чтобы объяснить возможность использования двух- или трехканальных массивов в cv2.transform()
,
Канал — это последнее измерение исходного массива. Давайте сначала прочитаем документы cv2.transform().
На вопрос :
Поскольку функция преобразует каждый элемент из параметра , размерность должна быть больше 2.
import cv2
import numpy as np
rotation_mat = np.array([[0.8660254, 0.5, -216.41978046], [-0.5, 0.8660254, 264.31038357]]) # 2x3
rotate_box = np.array([[410, 495], [756, 295], [956, 642], [610, 842]]) # 2x2
result_box = cv2.transform(rotate_box, rotation_mat) # error: (-215:Assertion failed) scn == m.cols || scn + 1 == m.cols in function 'transform'
Причина в размерности каждого элемента
rotate_box
является
(2,)
. Преобразование путем умножения на матрицы не может продолжаться.
К другому ответу : пока подходит последнее измерение, другие измерения не имеют значения. Продолжите приведенный выше фрагмент:
rotate_box_1 = np.array([rotate_box]) # 1x4x2
result_box = cv2.transform(rotate_box_1, rotation_mat) # 1x4x2
rotate_box_2 = np.array([[[410, 495]], [[756, 295]], [[956, 642]], [[610, 842]]]) # 4x1x2
result_box = cv2.transform(rotate_box_2, rotation_mat) # 4x1x2
Читателю : обратите внимание на форму, возвращаемую
cv2.transform()
такое же, как
src
.