2017-04-01 109 views
1

我无法理解the documentation for cv2.transform。请问有人可惜(并用Python解释)?将转换矩阵应用于opencv中的点列表(Python)

我有一个绘制多边形,在填充它,并且将图像旋转

import numpy as np 
import cv2 

dx,dy = 400,400 
centre = dx//2,dy//2 
img = np.zeros((dy,dx),np.uint8) 

# construct a long thin triangle with the apex at the centre of the image 
polygon = np.array([(0,0),(100,10),(100,-10)],np.int32) 
polygon += np.int32(centre) 

# draw the filled-in polygon and then rotate the image 
cv2.fillConvexPoly(img,polygon,(255)) 
M = cv2.getRotationMatrix2D(centre,20,1) # M.shape = (2, 3) 
rotatedimage = cv2.warpAffine(img,M,img.shape) 

我想先旋转多边形,然后代码绘制

# this is clumsy, I have to extend each vector, 
# apply the matrix to each extended vector, 
# and turn the list of transformed vectors into an numpy array 
extendedpolygon = np.hstack([polygon,np.ones((3,1))]) 
rotatedpolygon = np.int32([M.dot(x) for x in extendedpolygon]) 
cv2.fillConvexPoly(img,rotatedpolygon,(127)) 

我想这样做在一个函数调用,但我无法得到它的权利

# both of these calls produce the same error 
cv2.transform(polygon,M) 
cv2.transform(polygon.T,M) 
# OpenCV Error: Assertion failed (scn == m.cols || scn + 1 == m.cols) in transform, file /home/david/opencv/modules/core/src/matmul.cpp, line 1947 

我怀疑它的那句“src - 输入数组必须具有与m.cols或m.cols-1一样多的通道(1到4)“,我正在处理它。我认为polygon.T作为三个坐标与X和Y部分作为单独的渠道将资格,但可悲的是不。

我知道同样的问题已经被问到C++,我想在Python中得到答案。

+0

这是一个提示吗?正如我在原始问题中所写的, M = cv2.getRotationMatrix2D(center,20,1)#M.shape =(2,3) 这就是为什么我必须在每个向量中追加一个条目到多边形中的每个向量之前可以计算 [M.dot(x)for x in extendedpolygon] 我推测M.shape =(2,3)意味着M.row = 2,M.col = 3所以我不明白为什么我得到了我做的错误信息。 –

+0

这里是一个如何格式化点的例子。我不知道python/numpy,所以我不能帮你解释格式... http://dsp.stackexchange.com/questions/38626/image-preprocessing-for-facial-detection-embedding-clustering-管道.reshape应该是你在找什么。 – Micka

+1

感谢米卡,我寻找一个使用的例子,但没有找到一个。 –

回答

2

我感谢Micka指出我的一个实例。这里是代码,提供了我的问题的答案。

import numpy as np 
import cv2 

dx,dy = 400,400 
centre = dx//2,dy//2 
img = np.zeros((dy,dx),np.uint8) 

# construct a long thin triangle with the apex at the centre of the image 
polygon = np.array([(0,0),(100,10),(100,-10)],np.int32) 
polygon += np.int32(centre) 

# draw the filled-in polygon and then rotate the image 
cv2.fillConvexPoly(img,polygon,(255)) 
M = cv2.getRotationMatrix2D(centre,20,1) # M.shape = (2, 3) 
rotatedimage = cv2.warpAffine(img,M,img.shape) 

# as an alternative, rotate the polygon first and then draw it 

# these are alternative ways of coding the working example 
# polygon.shape is 3,2 

# magic that makes sense if one understands numpy arrays 
poly1 = np.reshape(polygon,(3,1,2)) 
# slightly more accurate code that doesn't assumy the polygon is a triangle 
poly2 = np.reshape(polygon,(polygon.shape[0],1,2)) 
# turn each point into an array of points 
poly3 = np.array([[p] for p in polygon]) 
# use an array of array of points 
poly4 = np.array([polygon]) 
# more magic 
poly5 = np.reshape(polygon,(1,3,2)) 

for poly in (poly1,poly2,poly3,poly4,poly5): 
    newimg = np.zeros((dy,dx),np.uint8) 
    rotatedpolygon = cv2.transform(poly,M) 
    cv2.fillConvexPoly(newimg,rotatedpolygon,(127)) 

说实话,我不明白为什么cv2.fillConvexPoly()接受前三个答案,但它似乎是非常宽容的,我还是不明白,这些答案如何映射到文档。