让 cv.transform 工作有困难

trouble getting cv.transform to work

我想在一些单独的 (x,y) 点上使用与我在 cv2.warpAffine 图像上使用的相同的仿射矩阵 M。看来 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' 通道,但是那么第三个是什么,不同的行表示什么?

Python 上的 OpenCV 通常需要

形式的点
np.array([ [[x1, y1]], ..., [[xn, yn]] ])

这在 documentation for cv2.transform() but is more clear in the documentation for other functions that use points, like cv2.perspectiveTransform() 中并不清楚,他们提到坐标在不同的频道上:

src – input two-channel or three-channel floating-point array

变换也可以在 3D 中使用(使用 4x4 透视变换矩阵),这样就可以解释使用两个 三通道阵列的能力cv2.transform().

通道是源数组的最后一个维度。先看一下cv2.transform()的文档


对问题:

因为函数从参数src转换每个元素,所以src的维数要求大于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

致reader: 请注意 cv2.transform() 返回的形状与 src.

相同