De OpenCV Python-bibliotheek heeft het mogelijk gemaakt om het proces van het samenvoegen van meerdere afbeeldingen tot één panoramische afbeelding te automatiseren.

Panoramische fotografie is de techniek van het vastleggen van een breder gezichtsveld dat een enkele foto niet kan bereiken. Deze techniek hecht meerdere afbeeldingen aan elkaar om één afbeelding te creëren die de hele scène op een meeslepende manier vastlegt.

Met behulp van Python kunt u dit proces automatiseren en met gemak prachtige panorama's maken.

Uw Python-omgeving opzetten

Om door te gaan, moet u een basiskennis van Python. Start een Python IDE en creëer een nieuwe virtuele omgeving. Maak een nieuw Python-bestand. En voer op de terminal de volgende opdracht uit om OpenCV te installeren.


pip installeer opencv-contrib-python

Je maakt gebruik van de opencv-contrib-python bibliotheek om afbeeldingen te laden en te manipuleren. Het heeft de cv2.Stitcher klasse die u gaat gebruiken om de panorama's te maken.

De volledige broncode en voorbeeldafbeeldingen die in dit artikel zijn gebruikt, zijn hierin beschikbaar

instagram viewer
GitHub-opslagplaats.

De vereiste bibliotheken importeren

Importeer de cv2 En os modules in uw script. U gebruikt het besturingssysteem om door de systeempaden te navigeren.

importeren cv2
importeren os

De OS-module is een ingebouwde module van Python. Dit is de reden dat u het niet extern hoeft te installeren.

De afbeeldingen laden

Maak een functie voor het laden van de afbeeldingen die u wilt samenvoegen. Maak eerst een lege lijst waarin de eerste afbeeldingen worden opgeslagen. Loop vervolgens door elk bestand in het mappad en controleer of het bestand een afbeelding is. Als het een afbeelding is, laadt u deze en voegt u deze toe aan de lijst met afbeeldingen.


deflaad afbeeldingen(map_pad):
# Laad afbeeldingen uit een map en verklein ze.
afbeeldingen = []
voor bestandsnaam in os.listdir (map_pad):
# Controleer of het bestand een afbeeldingsbestand is
als bestandsnaam.eindigt met('.jpg') of bestandsnaam.eindigt met('.png'):
# Laad de afbeelding met OpenCV en verklein deze
afbeelding = cv2.imread (os.pad.join (map_pad, bestandsnaam))
afbeeldingen.toevoegen (afbeelding)
opbrengst afbeeldingen

U kunt meer afbeeldingsbestandsindelingen toevoegen om uw programma te diversifiëren. Deze code zoekt alleen naar .jpg En .png bestandsformaten.

Het formaat van de afbeeldingen wijzigen voor een uniforme steek en snellere verwerking

Maak een functie die de grootte van de lijst met afbeeldingen wijzigt. De functie doorloopt elke afbeelding in de lijst en wijzigt de grootte ervan. Voeg ten slotte de verkleinde afbeeldingen toe aan een nieuwe lijst.


defgrootte_afbeeldingen wijzigen(afbeeldingen, breedte, hoogte):
resized_images = []
voor afbeelding in afbeeldingen:
resized_image = cv2.resize (afbeelding, (breedte, hoogte))
resized_images.append (resized_image)
opbrengst verkleinde_afbeeldingen

Formaat wijzigen zorgt ervoor dat het samenvoegen van de afbeeldingen uniform is. Het verkleint ook de bestandsgrootte voor snellere verwerking.

De Stitcher-module van OpenCV gebruiken om de afbeeldingen te naaien

Creëer een functie om de verkleinde afbeeldingen aan elkaar te hechten. Deze techniek staat algemeen bekend als het maken van een panorama. De functie neemt een lijst met afbeeldingen als invoer. Gebruik de Stikster module om ze aan elkaar te naaien. Ten slotte retourneert de functie een samengevoegde afbeelding en een statuscode.


defsteek_afbeeldingen(afbeeldingen):
stitcher = cv2.Stitcher.create()
(status, stitched_image) = stitcher.stitch (afbeeldingen)
als status == cv2.STITCHER_OK:
opbrengst gestikt_afbeelding
anders:
opbrengstGeen

Als het naaien is gelukt (zoals aangegeven door de cv2.STITCHER_OK statuscode), retourneert de functie de samengevoegde afbeelding. Anders komt het terug Geen.

De samengevoegde afbeelding bijsnijden

Maak een functie die de samengevoegde afbeelding opneemt en retourneert nadat deze is bijgesneden. Converteer eerst de samengevoegde afbeelding naar grijstinten. Pas vervolgens een binaire drempel toe om een ​​binaire afbeelding te maken. Zoek ten slotte de grootste contour in de binaire afbeelding en bereken de begrenzende rechthoek.


defafbeelding bijsnijden(afbeelding):
grijs = cv2.cvtColor (afbeelding, cv2.COLOR_BGR2GRAY)
drempel = cv2.drempel (grijs, 0, 255, cv2.THRESH_BINARY)[1]
contouren = cv2.findContours (dors, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
x, y, w, h = cv2.boundingRect (contouren[0])
cropped_image = afbeelding[y: y + h, x: x + w]
opbrengst bijgesneden_afbeelding

De samengevoegde afbeelding wordt bijgesneden met behulp van de omsluitende rechthoek.

Een voorbeeld bekijken en de gestikte afbeelding opslaan met behulp van OpenCV

Maak een functie die de samengevoegde afbeelding in een interactief venster weergeeft en deze op de schijf opslaat.


defpreview_and_save_image(afbeelding, map_pad, mapnaam):
# Geef de samengevoegde afbeelding weer
cv2.namedWindow('Gestikte afbeelding', cv2.WINDOW_NORMAL)
cv2.imshow('Gestikte afbeelding', afbeelding)
cv2.waitKey(0)

# Sla de gestikte afbeelding op
output_filename = os.path.join (map_pad, mapnaam + '_panorama.jpg')
cv2.imwrite (uitvoer_bestandsnaam, afbeelding)
afdrukken('Gestikte afbeelding opgeslagen voor map:', naam van de map)

Het panoramabeeld wordt opgeslagen in dezelfde map die de originele beelden bevat.

De stroom van uw programma beheersen

Maak een functie die de stroom van uw programma regelt. Het laadt alle afbeeldingen uit de opgegeven map. Pas het formaat aan en naai ze aan elkaar. Snijd de samengevoegde afbeelding bij, geef het voorbeeld weer en sla het vervolgens op schijf op. Als er minder dan twee afbeeldingen in de map staan, drukt de functie een foutmelding af en keert terug zonder samenvoegen of opslaan.


defsteek_map(map_pad, breedte=800, hoogte=800):
# Steek alle afbeeldingen in een map en sla het resultaat op.
# Laad de afbeeldingen uit de map
afbeeldingen = load_images (map_pad)

# Controleer of er ten minste twee afbeeldingen in de map staan
als len (afbeeldingen) < 2:
afdrukken('Niet genoeg afbeeldingen in map:', map_pad)
opbrengst

# Wijzig het formaat van de afbeeldingen
resized_images = resize_images (afbeeldingen, breedte, hoogte)

# Steek de afbeeldingen
stitched_image = stitch_images (verkleinde_afbeeldingen)
als gestikt_afbeelding isGeen:
afdrukken('Stitching mislukt voor map:', map_pad)
opbrengst

# Snijd de gestikte afbeelding bij
cropped_image = crop_image (gestikte_afbeelding)

# Bekijk een voorbeeld en sla de gestikte afbeelding op
folder_name = os.path.basename (folder_path)
preview_and_save_image (bijgesneden_afbeelding, mappad, mapnaam)

Geef het mappad door met de afbeeldingen die u wilt samenvoegen.

stitch_folder('sample_images') 

De afbeeldingen die u gebruikt, moeten overlappende kenmerken bevatten. Deze functies kunnen van alles zijn, van prominente oriëntatiepunten tot textuurpatronen in de afbeelding. OpenCV gebruikt ze als referentiepunt om de afbeeldingen uit te lijnen.

Zonder deze functies zal het voor OpenCV moeilijk zijn om de afbeeldingen uit te lijnen en een naadloos panorama te creëren.

Uw programma testen

Verzamel de afbeeldingen die u wilt omzetten in een panorama-afbeelding. Zorg ervoor dat ze overlappende kenmerken hebben.

Kijk eens naar de heuvel in deze eerste afbeelding.

Op deze tweede afbeelding is de heuvel enigszins zichtbaar. Dit creëert een overlappende functie.

Sla de afbeeldingen op in een map. Geef het mappad door aan het steek_map functie voor naaien. En voer dan het programma uit.

Het programma hechtte de beelden aan elkaar en creëerde een panoramisch beeld met een breder zicht op de scène. Merk op dat om de bovenstaande panoramische afbeelding te maken, negen afbeeldingen zijn gebruikt die aanwezig zijn in de bovengenoemde GitHub-repository.

Manipulatie van afbeeldingen met behulp van OpenCV

Het maken van panorama's demonstreert enkele van de vele beeldmanipulatietechnieken die OpenCV biedt. Er zijn meer technieken die u kunt gebruiken om afbeeldingen naar wens te manipuleren. Door aan meer projecten met beeldmanipulatie te werken, kunt u uw computervisie in het algemeen verbeteren.