2017-04-01 92 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()接受前三個答案,但它似乎是非常寬容的,我還是不明白,這些答案如何映射到文檔。