2017-02-20 2 views
1

Je construis un projet simple en Python3, en utilisant OpenCV3, essayant de faire correspondre des pièces de puzzle à l'image de puzzle "fini". J'ai commencé mes tests en utilisant SIFT.OpenCV Python Feature Detection: comment fournir un masque? (SIFT)

Je peux extraire le contour de la pièce de puzzle et recadrer l'image mais comme la plupart des hautes fréquences résident bien sûr autour de la pièce (où la pièce se termine et le sol commence), je veux passer un masque la méthode SIFT detectAndCompute(), forçant ainsi l'algorithme à rechercher les keypoints uniquement dans la pièce.

test_mask = np.ones(img1.shape, np.uint8) 
kp1, des1 = sift.detectAndCompute(img1, mask = test_mask) 

Après avoir passé un masque de test (pour vous assurer qu'il est uint8), je reçois l'erreur suivante:

kp1, des1 = sift.detectAndCompute(img1,mask = test_mask) cv2.error: /home/pyimagesearch/opencv_contrib/modules/xfeatures2d/src/sift.cpp:772: error: (-5) mask has incorrect type (!=CV_8UC1) in function detectAndCompute

D'après mes recherches, uint8 est juste un alias pour CV_8U, qui est le même que CV_8UC1. Impossible de trouver un échantillon de code transmettant un masque à un algorithme de détection de fonctionnalité en Python.

+0

Si 'img1' est une image couleur, il a 3 canaux, donc votre masque finit par être de type' CV_8UC3' car vous utilisez 'img1.shape', qui est quelque chose comme' [rows, cols, 3] '. Vous devez créer un masque à un seul canal. – Miki

+0

J'utilisais également un masque binaire créé avec une méthode différente et je supposais que c'était [rows, cols, 1] mais grâce à votre réponse, j'ai découvert que quelque part, il était converti en image à 3 canaux. Je vous remercie! Et désolé pour le problème (essayant toujours de comprendre le contrôle de type en Python). Est-ce que je peux accepter votre commentaire comme réponse? – m3h0w

+0

Heureux que cela a aidé. Il suffit d'écrire une réponse avec le code correct et l'explication – Miki

Répondre

1

Grâce à Miki, j'ai réussi à trouver un bug.

Il s'est avéré que mon masque d'origine que j'ai créé en utilisant des opérations de seuil, même si regardé binaire, était une image à trois canaux ([rows], [cols], 3). Ainsi, il ne pouvait pas être accepté comme un masque.

Après avoir vérifié pour le type et la forme (doit être uint8 et [rangées, cols, 1]):

print(mask.dtype) 
print(mask.shape) 

Autre masque à gris si elle est toujours trois canaux:

mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)