La photographie panoramique est une technique qui permet de capturer un champ de vision plus large qu’une seule photographie ne peut atteindre. Cette technique permet d’assembler plusieurs images pour créer une seule image qui capture l’ensemble de la scène de manière immersive.


Avec l’aide de Python, vous pouvez automatiser ce processus et créer facilement de magnifiques panoramas.

Configuration de l’environnement Python

Pour continuer, vous devez avoir une connaissance de base de Python. Lancez n’importe quel IDE Python et créez un nouvel environnement virtuel. Créez un nouveau fichier Python. Dans le terminal, exécutez la commande suivante pour installer OpenCV.

 
pip install opencv-contrib-python

Vous utiliserez la commande opencv-contrib-python pour charger des images et les manipuler. Elle dispose de l’option cv2.Stitcher que vous utiliserez pour créer les panoramas.

Le code source complet et les exemples d’images utilisés dans cet article sont disponibles dans ce dépôt GitHub.

Importer les bibliothèques nécessaires

Importer les bibliothèques cv2 et os dans votre script. Vous utiliserez OS pour naviguer dans les chemins du système.

 import cv2
import os

Le module OS est un module intégré à Python. C’est la raison pour laquelle vous n’avez pas besoin de l’installer en externe.

Chargement des images

Créez une fonction pour charger les images que vous souhaitez assembler. Tout d’abord, créez une liste vide qui stockera les images initiales. Ensuite, on parcourt en boucle chaque fichier dans le chemin du dossier en vérifiant s’il s’agit d’une image. S’il s’agit d’une image, chargez-la et ajoutez-la à la liste des images.

 
def load_images(folder_path):
    # Load images from a folder and resize them.
    images = []
    for filename in os.listdir(folder_path):
        # Check if file is an image file
        if filename.endswith('.jpg') or filename.endswith('.png'):
            # Load the image using OpenCV and resize it
            image = cv2.imread(os.path.join(folder_path, filename))
            images.append(image)
    return images

Vous pouvez ajouter d’autres formats de fichiers image pour diversifier votre programme. Ce code ne recherchera que .jpg et .png formats de fichiers.

Redimensionnement des images pour une couture uniforme et un traitement plus rapide

Créez une fonction qui redimensionnera la liste des images. La fonction passe en revue chaque image de la liste et la redimensionne. Enfin, elle ajoutera les images redimensionnées à une nouvelle liste.

 
def resize_images(images, width, height):
    resized_images = []
    for image in images:
        resized_image = cv2.resize(image, (width, height))
        resized_images.append(resized_image)
    return resized_images

Le redimensionnement permet de s’assurer que l’assemblage des images est uniforme. Il réduit également la taille du fichier pour un traitement plus rapide.

Utilisation du module Stitcher d’OpenCV pour l’assemblage des images

Créez une fonction pour assembler les images redimensionnées. Cette technique est communément appelée création d’un panorama. La fonction prend une liste d’images en entrée. Utilisez la fonction Assembleur pour les assembler. Enfin, la fonction renvoie une image assemblée et un code d’état.

 
def stitch_images(images):
    stitcher = cv2.Stitcher.create()
    (status, stitched_image) = stitcher.stitch(images)
    if status == cv2.STITCHER_OK:
        return stitched_image
    else:
        return None

Si l’assemblage a réussi (comme indiqué par le code d’état cv2.STITCHER_OK ), la fonction renvoie l’image assemblée. Sinon, elle renvoie Aucun.

Recadrage de l’image assemblée

Créez une fonction qui prendra en charge l’image assemblée et la renverra après l’avoir recadrée. Commencez par convertir l’image piquée en niveaux de gris. Ensuite, appliquez un seuil binaire pour créer une image binaire. Enfin, trouvez le plus grand contour dans l’image binaire et calculez son rectangle de délimitation.

 
def crop_image(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
    contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
    x, y, w, h = cv2.boundingRect(contours[0])
    cropped_image = image[y:y + h, x:x + w]
    return cropped_image

L’image assemblée est recadrée à l’aide du rectangle de délimitation.

Prévisualisation et sauvegarde de l’image assemblée à l’aide d’OpenCV

Créez une fonction qui affichera l’image assemblée dans une fenêtre interactive et qui l’enregistrera sur le disque.

 
def preview_and_save_image(image, folder_path, folder_name):
    # Display the stitched image
    cv2.namedWindow('Stitched Image', cv2.WINDOW_NORMAL)
    cv2.imshow('Stitched Image', image)
    cv2.waitKey(0)

    # Save the stitched image
    output_filename = os.path.join(folder_path, folder_name + '_panorama.jpg')
    cv2.imwrite(output_filename, image)
    print('Stitched image saved for folder:', folder_name)

L’image panoramique est enregistrée dans le même dossier que les images originales.

Contrôler le déroulement de votre programme

Créez une fonction qui contrôlera le déroulement de votre programme. Elle chargera toutes les images du dossier spécifié. Les redimensionner et les assembler. Recadrer l’image assemblée, afficher sa prévisualisation, puis l’enregistrer sur le disque. S’il y a moins de deux images dans le dossier, la fonction affichera un message d’erreur et reviendra sans effectuer d’assemblage ni d’enregistrement.

 
def stitch_folder(folder_path, width=800, height=800):
    # Stitch all images in a folder and save the result.
    # Load the images from the folder
    images = load_images(folder_path)

    # Check if there are at least two images in the folder
    if len(images) < 2:
        print('Not enough images in folder:', folder_path)
        return

    # Resize the images
    resized_images = resize_images(images, width, height)

    # Stitch the images
    stitched_image = stitch_images(resized_images)
    if stitched_image is None:
        print('Stitching failed for folder:', folder_path)
        return

    # Crop the stitched image
    cropped_image = crop_image(stitched_image)

    # Preview and save the stitched image
    folder_name = os.path.basename(folder_path)
    preview_and_save_image(cropped_image, folder_path, folder_name)

Indiquez le chemin d’accès au dossier contenant les images à assembler.

stitch_folder('sample_images')

Les images que vous utilisez doivent contenir des éléments qui se chevauchent. Ces caractéristiques peuvent être des points de repère importants ou des motifs de texture dans l’image. OpenCV les utilise comme point de référence pour aligner les images.

Sans ces caractéristiques, il sera difficile pour OpenCV d’aligner les images et de créer un panorama homogène.

Tester votre programme

Rassemblez les images que vous souhaitez transformer en une image panoramique. Veillez à ce que leurs caractéristiques se chevauchent.

Observez la colline sur cette première image.

Image d'une scène avec une colline affichée

Sur cette deuxième image, la colline est légèrement visible. Cela crée un élément de chevauchement.

Image d'une scène avec un bâtiment et une colline légèrement visible

Enregistrez les images dans un dossier. Transmettez le chemin d’accès au dossier à la fonction dossier_piquage pour la piqûre. Exécutez ensuite le programme.

Une image panoramique en sortie de programme

Le programme a assemblé les images et créé une image panoramique avec une vue plus large de la scène. Pour créer l’image panoramique ci-dessus, neuf images présentes dans le dépôt GitHub susmentionné ont été utilisées.

Manipulation d’images à l’aide d’OpenCV

La création de panoramas illustre quelques-unes des nombreuses techniques de manipulation d’images offertes par OpenCV. Il existe d’autres techniques que vous pouvez utiliser pour manipuler des images en fonction de vos besoins. Travailler sur d’autres projets impliquant la manipulation d’images vous aidera à améliorer vos compétences en vision par ordinateur en général.