让 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
.
相同
我想在一些单独的 (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
.