J'essaie d'utiliser OpenCV avec Python. J'ai écrit un descripteur (tamis, surf ou orb) Code correspondant dans la version C ++ de OpenCV 2.4. Je veux convertir ce code en openc avec Python. J'ai trouvé des documents sur la manière d'utiliser les fonctions OPENCV en C ++, mais bon nombre de la fonction OPENCV dans Python, je n'ai pas pu trouver comment les utiliser. Voici mon code Python et mon problème actuel est que je ne sais pas comment utiliser "Drawmatches" de OpenCV C ++ à Python. J'ai trouvé cv2.draw_matches_flags_default mais je ne sais pas comment l'utiliser. Voici mon code Python de correspondance à l'aide des descripteurs Orb:
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'long' object is not callable
3 Réponses :
Comme le dit le message d'erreur, draw_matches_flags_default est de type "long". C'est une constante définie par le module CV2, pas une fonction. Malheureusement, la fonction que vous souhaitez, 'Drawmatches' n'existe que dans l'interface C ++ de OpenCV. P>
Plus vrai. Il existe maintenant dans OpenCV 3.x et 4.x. Cependant, les réponses ci-dessus sont des solutions de contournement pour OpenCV 2.x.
Vous pouvez visualiser la fonctionnalité correspondant à Python comme suit. Notez l'utilisation de la bibliothèque SciPy.
# matching features of two images import cv2 import sys import scipy as sp if len(sys.argv) < 3: print 'usage: %s img1 img2' % sys.argv[0] sys.exit(1) img1_path = sys.argv[1] img2_path = sys.argv[2] img1 = cv2.imread(img1_path, cv2.CV_LOAD_IMAGE_GRAYSCALE) img2 = cv2.imread(img2_path, cv2.CV_LOAD_IMAGE_GRAYSCALE) detector = cv2.FeatureDetector_create("SURF") descriptor = cv2.DescriptorExtractor_create("BRIEF") matcher = cv2.DescriptorMatcher_create("BruteForce-Hamming") # detect keypoints kp1 = detector.detect(img1) kp2 = detector.detect(img2) print '#keypoints in image1: %d, image2: %d' % (len(kp1), len(kp2)) # descriptors k1, d1 = descriptor.compute(img1, kp1) k2, d2 = descriptor.compute(img2, kp2) print '#keypoints in image1: %d, image2: %d' % (len(d1), len(d2)) # match the keypoints matches = matcher.match(d1, d2) # visualize the matches print '#matches:', len(matches) dist = [m.distance for m in matches] print 'distance: min: %.3f' % min(dist) print 'distance: mean: %.3f' % (sum(dist) / len(dist)) print 'distance: max: %.3f' % max(dist) # threshold: half the mean thres_dist = (sum(dist) / len(dist)) * 0.5 # keep only the reasonable matches sel_matches = [m for m in matches if m.distance < thres_dist] print '#selected matches:', len(sel_matches) # ##################################### # visualization of the matches h1, w1 = img1.shape[:2] h2, w2 = img2.shape[:2] view = sp.zeros((max(h1, h2), w1 + w2, 3), sp.uint8) view[:h1, :w1, :] = img1 view[:h2, w1:, :] = img2 view[:, :, 1] = view[:, :, 0] view[:, :, 2] = view[:, :, 0] for m in sel_matches: # draw the keypoints # print m.queryIdx, m.trainIdx, m.distance color = tuple([sp.random.randint(0, 255) for _ in xrange(3)]) cv2.line(view, (int(k1[m.queryIdx].pt[0]), int(k1[m.queryIdx].pt[1])) , (int(k2[m.trainIdx].pt[0] + w1), int(k2[m.trainIdx].pt[1])), color) cv2.imshow("view", view) cv2.waitKey()
Lors de l'exécution de votre code, j'obtiens une erreur sur la ligne 66, TypeError: L'argument entier attendu, a été float code>
@ Wall-e Un utilisateur anonyme vient de modifier votre message, pourrait vouloir vérifier qu'ils ne le sont pas brisés
Voir [: H1,: W1,:] = IMG1 ValueError: Impossible de diffuser une matrice d'entrée de la forme (322 518) en forme (322 518,3)
OK Le problème est que l'IMG n'est pas toujours à 3 canaux car @Brainless a souligné. Cela dépend de la version OpenCV. Donc, dans mon cas (j'utilise 2.7.13), j'ai dû retourner à la version originale que Wall-e posté
J'ai aussi écrit quelque chose moi-même qui utilise simplement l'interface Python OpenCV et je n'ai pas utilisé J'ai fourni mes propres images où l'on est d'un homme de caméra, et l'autre est la même image mais tourné par 55 degrés dans le sens inverse des aiguilles d'une montre. P> La prémisse de base de ce que j'ai écrit est J'accepterais une image RVB de sortie où la quantité de lignes est le maximum des deux images pour accueillir les deux images de l'image de sortie et que les colonnes sont simplement la sommation des colonnes ensemble. Je place chaque image dans leurs endroits correspondants, puis passez à travers une boucle de tous les claviers correspondants. J'extrise lesquels les claviers correspondaient entre les deux images, puis extrayez leur Gardez à l'esprit que le clavier détecté dans la deuxième image concerne son propre système de coordonnées. Si vous souhaitez placer cela dans l'image de sortie finale, vous devez compenser la colonne coordonnée par la quantité de colonnes à partir de la première image de sorte que la colonne coordonnée soit par rapport au système de coordonnée de l'image de sortie de l'image. . P> sans autre ado: p> Pour illustrer que cela fonctionne, voici les deux images que j'ai utilisées: p> J'ai utilisé le détecteur d'orb d'OpenCV pour détecter les claviers et utiliser la distance de halogerie normalisée comme mesure de distance pour la similarité que ceci est un descripteur binaire. En tant que tel: p> Scipy code>.
Drawmatches Code> fait partie de OpenCV 3.0.0 et ne fait pas partie de OpenCV 2, ce qui vous utilise actuellement. Même si je suis en retard à la fête, voici ma propre implémentation qui imite
drawmatches code> au mieux de mes capacités.
(x, y) code> coordonnées. Je dessine ensuite des cercles à chacun des emplacements détectés, puis dessinez une ligne reliant ces cercles ensemble. P>
p>
p>
import numpy as np
import cv2
img1 = cv2.imread('cameraman.png') # Original image
img2 = cv2.imread('cameraman_rot55.png') # Rotated image
# Create ORB detector with 1000 keypoints with a scaling pyramid factor
# of 1.2
orb = cv2.ORB(1000, 1.2)
# Detect keypoints of original image
(kp1,des1) = orb.detectAndCompute(img1, None)
# Detect keypoints of rotated image
(kp2,des2) = orb.detectAndCompute(img2, None)
# Create matcher
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Do matching
matches = bf.match(des1,des2)
# Sort the matches based on distance. Least distance
# is better
matches = sorted(matches, key=lambda val: val.distance)
# Show only the top 10 matches
drawMatches(img1, kp1, img2, kp2, matches[:10])
Hii @rayryeng quand j'essaie de courir au-dessus du code, je reçois la trace de trace (dernier appel le dernier): fichier "orb1.py", ligne 33, dans
@BHUSHANPATIL - Lisez la doctrine de la fonction soigneusement b>. Il nécessite des images en niveaux de gris. Vous utilisez des images RGB B>. Vous devez convertir les images en niveaux de gris avant d'utiliser la fonction. Un appel simple cv2.cvtcolor code> devrait suffire:
img = cv2.cvtcolor (img, cv2.color_bgray) code> fonctionnera. Veuillez réellement lire la documentation de la fonction avant de l'utiliser la prochaine fois. Il s'agit d'une compétence standard que tous les développeurs doivent apprendre lors de l'utilisation du code de quelqu'un d'autre.