web-dev-qa-db-fra.com

Assembler plusieurs images avec OpenCV (Python)

Bonjour, j’ai vu beaucoup de tutoriels sur l’assemblage simple en utilisant deux photos et ce n’est pas un problème.
Mais que faire quand je veux faire un panorama à partir de 4 à 6 images ou plus?

J'ai un code qui prend en liste de fichiers image (les images sont en ordre de la première image de la séquence à la dernière). Ensuite, pour chaque image, je calcule les descripteurs de caractéristiques SIFT . Mais je suis bloqué. Pour deux images, je configurerais un adaptateur en utilisant FLANN kd-tree et trouverais des correspondances entre les images pour calculer l'homographie. Semblable à ce tutoriel http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_feature_homography/py_feature_homography.html#py-feature-homography

Mais au lieu de montrer les lignes entre les points caractéristiques à la fin, j’ai utilisé cette https://stackoverflow.com/a/20355545/622194 fonction pour créer un panorama à partir de 2 images. Mais je ne sais pas quoi faire lorsque je veux ajouter la troisième et la quatrième image au panorama.

MODIFIER: 

A partir des réponses, j'ai essayé d'implémenter mon script d'assemblage d'images pour calculer une matrice d'homographie entre des images proches les unes des autres dans la séquence d'images. Donc, si j'ai I1, I2, I3 et I4, j'ai maintenant H_12, H_23 et H_34. Ensuite, je commence par coudre I1 et I2 avec H_12. Ensuite, je veux trouver une homographie cumulative pour assembler I3 au panorama actuel. I fing H_13 = H_12 * H_23 et assemblez l'image 3 au panorama actuel, mais ici, il y a un écart très apparent dans mon image panoramique. Lorsque l'image suivante est assemblée, cet écart est encore plus grand et les images très étirées. Voici mon code http://Pastebin.com/dQjhE5VD

Quelqu'un peut-il me dire si j'utilise la bonne approche pour cela ou quelqu'un peut-il détecter l'erreur ou voir ce que je fais de travers? 

14
krunarsson

Pas à pas, en supposant que vous vouliez assembler quatre images I0, I1, I2, I3, votre objectif est de calculer les homographies H_0, H_1, H_2, H_3;

  1. Calculer toutes les homographies par paires H_01, H_02, H_03, H_12, H_13, H_23 où l'homographie H_01 convertit l'image I0 en I1, etc ...
  2. Sélectionnez une image d'ancrage, par exemple. I1 quelle position restera fixe i.e H_1 = Identité
  3. Trouvez une image qui correspond mieux à I1 en fonction du nombre maximal de correspondances cohérentes I3
  4. Mise à jour H_3 = H_1 * inv (H_13) = inv (H_13) = H_31
  5. Trouvez une image qui correspond mieux à I1 ou I3, par exemple I2 correspondant à I3
  6. Mise à jour H_2 = H_3 * H_23
  7. Comme ci-dessus pour l'image I0
  8. Effectuez les ajustements de paquet pour optimiser globalement l'alignement

Voir la section 4 de cet article précurseur Assemblage d'images panoramiques automatiques à l'aide de fonctions invariantes pour une explication détaillée.

12
memecs

Approche Hacky

Le moyen le plus simple (bien que pas très efficace) étant donné les fonctions que vous avez écrites, consiste simplement à agrandir l’image panoramique en la cousant à chaque image successive. Quelque chose comme ce pseudo-code:

panorama = images[0]
for i in 1:len(images)-1
    panorama = stitch(panorama,images[i])

Cette méthode tente essentiellement de faire correspondre l'image suivante à une partie du panorama actuel. Cela devrait fonctionner convenablement, en supposant que chaque nouvelle image se situe quelque part à la frontière du panorama actuel et qu'il n'y ait pas trop de distorsion de la perspective.

Approche mathématique

L'autre option, si vous connaissez l'ordre que vous voulez assembler, consiste à rechercher l'homographie d'une image à la suivante, puis à la multiplier. Le résultat est l'homographie de cette image à l'image 0. 

Par exemple: le H qui transforme l'image 3 pour s'aligner sur l'image 0 est H_03 = H_01 * H_12 * H_23. Où H_01 est le H qui transforme l’image 1 pour l’aligner sur l’image 0. (En fonction de la façon dont leur code définit H, vous devrez peut-être inverser l’ordre de multiplication ci-dessus.) Vous devez donc multiplier pour obtenir H_0i et l’utiliser ensuite image i à aligner avec l'image 0.

Pour en savoir plus sur la raison pour laquelle vous multipliez les transformations, voir: Transformations et multiplication de matrices plus précisément la partie "Composition des transformations".

4
Luke

J'ai eu le même problème avec les espaces entre les images. La première chose à faire est d’initialiser votre matrice d’homographie accumulée à la première image. Ensuite, à chaque nouvelle image, multipliez-la par la matrice d’homographie entre l’image actuelle et la suivante. Soyez conscient d'utiliser des matrices numpy et non des tableaux numpy. IDK pourquoi mais ils ont différentes routines de multiplication.

Voici mon code: 

def addFramePair(self, images, ratio=0.75, reprojThresh=4.0, showMatches=False):        
    (imageA, imageB) = images
    (kpsA, featuresA) = self.detectAndDescribe(imageA)
    (kpsB, featuresB) = self.detectAndDescribe(imageB)

    H = self.matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh)
    self.accHomography *= np.asmatrix(H)
    result = cv2.warpPerspective(imageA, np.linalg.inv(self.accHomography), (1600, 900))
    return result

imageA est actuelle, imageB est la suivante.

J'espère que cela t'aides.

1
Borys Tymchenko