2017-08-16 4 views
0

J'ai fait un petit exemple pour moi-même pour jouer avec OpenCVs wrapPerspective, mais la sortie n'est pas complètement comme prévu.OpenCV: Comprendre warpPerspective/perspective transformer

Mon entrée est une barre à un angle de 45 °. Je veux le transformer pour qu'il soit aligné verticalement/à un angle de 90 °. Aucun problème avec cela. Cependant, ce que je ne comprends pas, c'est que tout autour des points de destination réels est noir. La raison pour laquelle je ne comprends pas cela est qu'en fait seule la matrice de transformation est passée à la fonction wrapPerspective, pas aux points de destination eux-mêmes. Donc, mon résultat attendu serait une barre à un angle de 90 ° et la plupart autour d'être jaune au lieu de noir. Où est mon erreur de raisonnement?

# helper function 
def showImage(img, title): 
    fig = plt.figure() 
    plt.suptitle(title) 
    plt.imshow(img) 


# read and show test image 
img = mpimg.imread('test_transform.jpg') 
showImage(img, "input image") 


# source points 
top_left = [194,430] 
top_right = [521,103] 
bottom_right = [549,131] 
bottom_left = [222,458] 
pts = np.array([bottom_left,bottom_right,top_right,top_left]) 


# target points 
y_off = 400; # y offset 
top_left_dst = [top_left[0], top_left[1] - y_off] 
top_right_dst = [top_left_dst[0] + 39.6, top_left_dst[1]] 
bottom_right_dst = [top_right_dst[0], top_right_dst[1] + 462.4] 
bottom_left_dst = [top_left_dst[0], bottom_right_dst[1]] 
dst_pts = np.array([bottom_left_dst, bottom_right_dst, top_right_dst, top_left_dst]) 

# generate a preview to show where the warped bar would end up 
preview=np.copy(img) 
cv2.polylines(preview,np.int32([dst_pts]),True,(0,0,255), 5) 
cv2.polylines(preview,np.int32([pts]),True,(255,0,255), 1) 
showImage(preview, "preview") 


# calculate transformation matrix 
pts = np.float32(pts.tolist()) 
dst_pts = np.float32(dst_pts.tolist()) 
M = cv2.getPerspectiveTransform(pts, dst_pts) 

# wrap image and draw the resulting image 
image_size = (img.shape[1], img.shape[0]) 
warped = cv2.warpPerspective(img, M, dsize = image_size, flags = cv2.INTER_LINEAR) 
showImage(warped, "warped") 

Le résultat en utilisant ce code est:

enter image description here

Voici mon image d'entrée test_transform.jpg: enter image description here Et voici la même image avec coordonnées ajouté: enter image description here

Sur demande, voici la matrice de transformation:

[[ 6.05504680e-02 -6.05504680e-02 2.08289910e+02] 
[ 8.25714275e+00 8.25714275e+00 -5.12245707e+03] 
[ 2.16840434e-18 3.03576608e-18 1.00000000e+00]] 
+0

pouvez-vous la sortie de la matrice de transformation? Je pense qu'il y a une part assez importante de perspective. Si vous voulez juste effectuer une rotation 2D et une translation (transformation affine sans partie perspective), la dernière ligne doit être (0,0,1). Vous pouvez calculer une rotation 2D en la composant avec Translation (centre de rotation à 0), Rotation autour (0,0) (avec un certain angle) et une autre translation pour ramener le centre à la position d'origine ou à l'endroit où vous voulez que votre objet mis. Ces opérations peuvent être combinées en une seule matrice de transformation. – Micka

+0

@Micka: Ajout de la matrice de transformation à la fin de mon message initial. En fait, ce n'est qu'un exemple réduit/test, enfin je veux transformer les voies de rue (perspective de la voiture à la perspective bird eye) –

Répondre

2

Votre commande dans vos baies ou leurs positions pourrait être la cause de ce problème. Vérifiez cette image transformée: Le tableau dst_pts est: np.array ([[196,492], [233,494], [234,32], [196,34]]), qui ressemble plus ou moins au rectangle bleu de votre image d'aperçu. (j'ai fait moi-même les coordonnées pour vous assurer qu'ils sont à droite) REMARQUE: Vos points source et destination doivent être dans le bon ordre

enter image description here

+1

C'est la bonne réponse. Le 'top_left' de la barre inclinée correspond au' bottom_left' de la barre verticale (et tous les autres suivent la même erreur). Et c'est pourquoi le haut et le bas de la barre verticale est flou et pourquoi le jaune est si étroit dans OPs image déformée. –

+1

Merci les gars, vous deux avez raison! Les points de source de travail fixes pour moi étaient 'top_left = [521,103] top_right = [549,131] bottom_right = [222,458] bottom_left = [194,430]' et j'ai adapté le décalage: 'y_off = 50' –