Kuvien yhdistäminen OpenCV:llä ja Pythonilla

Tässä opetusohjelmassa opit suorittamaan kuvien yhdistämisen Pythonilla, OpenCV:llä ja cv2.createStitcher– ja cv2.Stitcher_create-funktioilla. Tämän päivän koodin avulla voit ommella useita kuvia yhteen ja luoda panoraaman ommelluista kuvista.

Vähän vajaat kaksi vuotta sitten julkaisin kaksi opasta kuvien ompelemisesta ja panoraaman rakentamisesta:

  1. Kuvan ompelun perusteet
  2. Reaaliaikainen panoraama ja kuvan ompelu

Kummassakin näistä oppaista käsiteltiin tyypillisen kuvan ommelualgoritmin perusteita, jotka vaativat vähintään neljä keskeistä vaihetta:

  1. Kärkipisteiden havaitseminen (DoG, Harris jne.) ja paikallisten invarianttien kuvaajien poimiminen (SIFT, SURF jne.) kahdesta sisääntulokuvasta
  2. Kuvien välisten kuvaajien sovittaminen yhteen
  3. RANSAC-algoritmin käyttäminen homografiamatriisin estimoimiseksi sovittujen ominaisvektoriemme avulla
  4. Vaiheen 3 avulla saadun homografiamatriisin käyttäminen poimintatransformaation soveltamiseen

Alkuperäisissä toteutuksissani suurin ongelma oli kuitenkin se, että ne eivät kyenneet käsittelemään yli kahta sisääntuloa.

Tämän päivän opetusohjelmassa käymme uudelleen läpi kuvien yhdistämistä OpenCV:llä, mukaan lukien sen, miten useampi kuin kaksi kuvaa voidaan yhdistää panoraamakuvaksi.

Oppiaksesi, miten kuvia yhdistetään OpenCV:llä ja Pythonilla, jatka lukemista!

Kuvien tikkaaminen OpenCV:llä ja Pythonilla

Tämän päivän opetusohjelman ensimmäisessä osassa käymme lyhyesti läpi OpenCV:n kuvien tikkausalgoritmin, joka on leivottu itse OpenCV-kirjastoon cv2.createStitcher– ja cv2.Stitcher_create-funktioiden avulla.

Sen jälkeen käymme läpi projektimme rakenteen ja toteutamme Python-skriptin, jota voidaan käyttää kuvien ompeluun.

Katselemme tämän ensimmäisen skriptin tuloksia, huomaamme sen rajoitukset ja sen jälkeen toteutamme toisen Python-skriptin, jota voidaan käyttää esteettisesti miellyttävämpien kuvien ompelutulosten aikaansaamiseksi.

Viimeiseksi käymme läpi toisen skriptin tulokset ja huomaamme jälleen mahdolliset rajoitukset tai haitat.

OpenCV:n kuvan ompelualgoritmi

Kuva 1: Stitcher-luokassa toteutettu ompelumoduulin putki (lähde).

Algoritmi, jota käytämme tänään, on samankaltainen kuin Brownin ja Lowen vuonna 2007 julkaistussa artikkelissa Automatic Panoramic Image Stitching with Invariant Features (Automaattinen panoraamakuvan ompelu invarianttien ominaisuuksien avulla) ehdottama menetelmä.

Toisin kuin aiemmat kuvien stitching-algoritmit, jotka ovat herkkiä syöttökuvien järjestykselle, Brownin ja Lowen menetelmä on kestävämpi, joten se ei ole herkkä:

  • Kuvien järjestys
  • Kuvien suuntaus
  • Valaistusvaihtelut
  • Kohinaiset kuvat, jotka eivät varsinaisesti kuulu panoraamakuvaan

Se lisäksi heidän kuvien ompelumenetelmänsä pystyy tuottamaan esteettisesti miellyttävämpiä ulostulopanoraamakuvia vahvistuksen kompensoinnin ja kuvien sulauttamisen avulla.

Algoritmin täydellinen ja yksityiskohtainen tarkastelu ei kuulu tämän postauksen piiriin, joten jos olet kiinnostunut oppimaan lisää, tutustu alkuperäiseen julkaisuun.

Projektin rakenne

Katsotaanpa, miten tämä projekti on järjestetty komennolla tree:

$ tree --dirsfirst.├── images│ └── scottsdale│ ├── IMG_1786-2.jpg│ ├── IMG_1787-2.jpg│ └── IMG_1788-2.jpg├── image_stitching.py├── image_stitching_simple.py└── output.png2 directories, 6 files

Syöttökuvat menevät images/-kansioon. Päätin tehdä alikansion scottsdale/ kuvieni joukolle siltä varalta, että haluan lisätä tänne myöhemmin lisää alikansioita.

Tänään tarkastelemme kahta Python-skriptiä:

  • image_stitching_simple.py : Yksinkertainen versiomme kuvien ompelemisesta voidaan toteuttaa alle 50 rivillä Python-koodia!
  • image_stitching.py : Tämä skripti sisältää hakkerini, jolla ommellaan ROI ommellusta kuvasta esteettisesti miellyttävää lopputulosta varten.

Viimeinen tiedosto, output.png , on tuloksena syntyvän ommellun kuvan nimi. Komentoriviargumenttien avulla voit helposti muuttaa tulostettavan kuvan tiedostonimeä + polkua.

Funktiot cv2.createStitcher ja cv2.Stitcher_create

Kuva 2: Konstruktorin allekirjoitus Stitcher-luokan objektin luomiseksi OpenCV:llä.

OpenCV:ssä on jo nyt toteutettu Brownin ja Lowen paperin kaltainen menetelmä cv2.createStitcher:n kautta (OpenCV 3.x) ja cv2.Stitcher_create (OpenCV 4) -funktioiden avulla.

Edellyttäen, että sinulla on OpenCV oikein konfiguroitu ja asennettu, voit tutkia cv2.createStitcher:n funktiosignatuuria OpenCV 3.x:lle:

createStitcher(...) createStitcher() -> retval

Huomaa, että tällä funktiolla on vain yksi parametri, try_gpu, jota voidaan käyttää parantamaan koko kuvien ompeluputkea. OpenCV:n GPU-tuki on rajallinen, enkä ole koskaan saanut tätä parametria toimimaan, joten suosittelen jättämään sen aina False .

OpenCV 4:n cv2.Stitcher_create-funktiolla on samanlainen allekirjoitus:

Stitcher_create(...) Stitcher_create() -> retval . @brief Creates a Stitcher configured in one of the stitching .modes. . . @param mode Scenario for stitcher operation. This is usually .determined by source of images to stitch and their transformation. .Default parameters will be chosen for operation in given scenario. . @return Stitcher class instance.

Toteuttaaksemme varsinaisen kuvien nitomisen meidän täytyy kutsua .stitch-metodia:

OpenCV 3.x:stitch(...) method of cv2.Stitcher instance stitch(images) -> retval, panoOpenCV 4.x:stitch(...) method of cv2.Stitcher instance stitch(images, masks) -> retval, pano . @brief These functions try to stitch the given images. . . @param images Input images. . @param masks Masks for each input image specifying where to .look for keypoints (optional). . @param pano Final pano. . @return Status code.

Tämä metodi hyväksyy listan syöttötiedoista images , ja yrittää sitten nitoa ne panoraamakuvaksi, jolloin se palauttaa ulostulevan panoraamakuvan kutsuvalle funktiolle.

Muuttuja status ilmaisee, onnistuiko kuvan ompelu vai ei, ja se voi olla yksi neljästä muuttujasta:

  • OK = 0 : Kuvan ompelu onnistui.
  • ERR_NEED_MORE_IMGS = 1 : Jos saat tämän tilakoodin, tarvitset lisää syöttökuvia panoraaman rakentamiseen. Tyypillisesti tämä virhe ilmenee, jos syöttökuvissa ei ole havaittu riittävästi avainpisteitä.
  • ERR_HOMOGRAPHY_EST_FAIL = 2 : Tämä virhe ilmenee, kun RANSAC-homografian estimointi epäonnistuu. Jälleen kerran saatat tarvita enemmän kuvia tai kuvissasi ei ole tarpeeksi erottuvia, ainutlaatuisia tekstuureja/objekteja, jotta avainpisteitä voitaisiin täsmällisesti sovittaa.
  • ERR_CAMERA_PARAMS_ADJUST_FAIL = 3 : En ole koskaan aiemmin kohdannut tätä virhettä, joten minulla ei ole paljon tietoa siitä, mutta pääpiirteissään se liittyy siihen, että kameran sisäisiä/ulkoisia ominaisuuksia ei pystytä kunnolla estimoimaan tulokuvista. Jos törmäät tähän virheeseen, saatat joutua tutustumaan OpenCV:n dokumentaatioon tai jopa sukeltamaan OpenCV:n C++-koodiin.

Nyt kun olemme käyneet läpi cv2.createStitcher , cv2.Stitcher_create ja .stitch metodit, siirrymme varsinaiseen kuvien yhdistämisen toteuttamiseen OpenCV:llä ja Pythonilla.

Kuvan ompelun toteuttaminen Pythonilla

Aloitetaan kuvan ompelualgoritmimme toteuttaminen!

Avaa image_stitching_simple.py-tiedosto ja lisää seuraava koodi:

# import the necessary packagesfrom imutils import pathsimport numpy as npimport argparseimport imutilsimport cv2# construct the argument parser and parse the argumentsap = argparse.ArgumentParser()ap.add_argument("-i", "--images", type=str, required=True,help="path to input directory of images to stitch")ap.add_argument("-o", "--output", type=str, required=True,help="path to the output image")args = vars(ap.parse_args())

Tarvitsemamme paketit tuodaan riveillä 2-6. Erityisesti käytämme OpenCV:tä ja imutilsia. Jos et ole vielä asentanut niitä, jatka niiden asentamista:

  • OpenCV:n asentamiseksi noudata yhtä OpenCV:n asennusoppaistani.
  • imutils-paketin voi asentaa/päivittää pipillä: pip install --upgrade imutils . Muista päivittää se, koska uusia ominaisuuksia lisätään usein.

Tästä analysoimme kaksi komentoriviargumenttia riveillä 9-14:

  • --images : Polku hakemistoon, jossa on ommeltavat syötekuvat.
  • --output : Polku tulostuskuvaan, johon tulos tallennetaan.

Jos et tunne käsitteitä argparse ja komentoriviargumentit, lue tämä blogikirjoitus.

Ladataan syöttökuvamme:

# grab the paths to the input images and initialize our images listprint(" loading images...")imagePaths = sorted(list(paths.list_images(args)))images = # loop over the image paths, load each one, and add them to our# images to stitch listfor imagePath in imagePaths:image = cv2.imread(imagePath)images.append(image)

Tässä nappaamme imagePaths (rivi 18).

Sitten jokaista imagePath varten lataamme image ja lisäämme sen images-listaan (rivit 19-25).

Nyt kun images ovat muistissa, jatketaan niiden yhdistämistä panoraamaksi OpenCV:n sisäänrakennetun kyvyn avulla:

# initialize OpenCV's image stitcher object and then perform the image# stitchingprint(" stitching images...")stitcher = cv2.createStitcher() if imutils.is_cv3() else cv2.Stitcher_create()(status, stitched) = stitcher.stitch(images)

Objekti stitcher luodaan rivillä 30. Huomaa, että riippuen siitä, käytätkö OpenCV 3:sta vai 4:stä, kutsutaan eri konstruktoria.

Sen jälkeen voimme siirtää images-objektimme .stitch-metodiin (rivi 31). Kutsu .stitch:lle palauttaa sekä status– että stitched-kuvamme (olettaen, että ompelu onnistui).

Viimeiseksi sekä (1) kirjoitamme ommellun kuvan levylle että (2) näytämme sen näytöllä:

# if the status is '0', then OpenCV successfully performed image# stitchingif status == 0:# write the output stitched image to diskcv2.imwrite(args, stitched)# display the output stitched image to our screencv2.imshow("Stitched", stitched)cv2.waitKey(0)# otherwise the stitching failed, likely due to not enough keypoints)# being detectedelse:print(" image stitching failed ({})".format(status))

Jos status-lippumme osoittaa onnistumista (rivi 35), kirjoitamme stitched-kuvan levylle (rivi 37) ja näytämme sen, kunnes näppäintä painetaan (rivit 40 ja 41).

Muussa tapauksessa tulostamme pelkän epäonnistumisilmoituksen (rivit 45 ja 46).

Basic image stitching results

Voidaksesi kokeilla kuvien yhdistämisskriptiämme, varmista, että lataat lähdekoodin ja esimerkkikuvat opetusohjelman ”Downloads”-osiosta.

Hakemiston images/scottsdale/ sisältä löydät kolme kuvaa, jotka otin vieraillessani Frank Lloyd Wrightin kuuluisassa Taliesin West -talossa Scottsdalessa, AZ:ssa:

Kuva 3: Kolme kuvaa, joiden avulla voit testata OpenCV:n kuvien ompelua. Nämä kuvat otin Scottsdalessa, AZ:ssa Frank Lloyd Wrightin kuuluisassa Taliesin West -talossa.

Tarkoituksenamme on nitoa nämä kolme kuvaa yhdeksi panoraamakuvaksi. Yhdistämisen suorittamiseksi avaa terminaali, siirry paikkaan, josta latasit koodin + kuvat, ja suorita seuraava komento:

$ python image_stitching_simple.py --images images/scottsdale --output output.png loading images... stitching images...
Kuva 4: OpenCV:llä suoritettu kuvien yhdistäminen. Tähän kuvaan on tehty kuvan ompelu, mutta sitä ei ole vielä rajattu.

Huomaa, kuinka olemme onnistuneesti suorittaneet kuvan ompelun!

Mutta entä nuo panoraamaa ympäröivät mustat alueet? Mitä ne ovat?

Nämä alueet ovat peräisin panoraaman rakentamiseen tarvittavien perspektiivivääristymien suorittamisesta.

On olemassa keino päästä niistä eroon… mutta meidän täytyy toteuttaa seuraavassa osiossa hieman lisälogiikkaa.

Parempi kuvanpistotoiminto OpenCV:llä ja Pythonilla

Kuva 5: Tässä osiossa opimme parantamaan kuvanpistotoimintoa OpenCV:llä rajaamalla panoraaman alue pois kuvassa näkyvän punaisella katkoviivalla rajatun rajan sisäpuolelta.

Ensimmäinen kuvanpistotoimintoskriptimme oli hyvä alku, mutta nuo mustat alueet, jotka ympäröivät varsinaista panoraamakuvausta, eivät ole jotakin sellaista, jota sanoisimme esteettisesti miellyttäväksi.

Ja mikä tärkeintä, et näkisi tällaista tulostuskuvaa suosituista kuvien stitching-sovelluksista, jotka on rakennettu iOS:ään, Androidiin jne.

Sentähden aiomme hakkeroida skriptiämme hieman ja sisällyttää siihen jonkin verran lisälogiikkaa luodaksemme esteettisesti miellyttävämpiä panoraamakuvia.

Kerron vielä kerran, että tämä menetelmä on hakkerointia.

Katselemme kuvankäsittelyn perusoperaatioita, kuten kynnysarvoja, ääriviivojen louhintaa, morfologisia operaatioita jne. saadaksemme haluamamme tuloksen.

Tietääkseni OpenCV:n Python-sidonnaisuus ei tarjoa meille tarvittavia tietoja, jotta voisimme manuaalisesti louhia panoraaman suurimman sisemmän suorakulmaisen alueen. Jos OpenCV:llä on, kertokaa se minulle kommenteissa, sillä haluaisin tietää sen mielelläni.

Aloitetaanpa – avaa image_stitching.py-skripti ja lisää seuraava koodi:

# import the necessary packagesfrom imutils import pathsimport numpy as npimport argparseimport imutilsimport cv2# construct the argument parser and parse the argumentsap = argparse.ArgumentParser()ap.add_argument("-i", "--images", type=str, required=True,help="path to input directory of images to stitch")ap.add_argument("-o", "--output", type=str, required=True,help="path to the output image")ap.add_argument("-c", "--crop", type=int, default=0,help="whether to crop out largest rectangular region")args = vars(ap.parse_args())# grab the paths to the input images and initialize our images listprint(" loading images...")imagePaths = sorted(list(paths.list_images(args)))images = # loop over the image paths, load each one, and add them to our# images to stich listfor imagePath in imagePaths:image = cv2.imread(imagePath)images.append(image)# initialize OpenCV's image sticher object and then perform the image# stitchingprint(" stitching images...")stitcher = cv2.createStitcher() if imutils.is_cv3() else cv2.Stitcher_create()(status, stitched) = stitcher.stitch(images)

Koko tämä koodi on identtinen edellisen skriptimme kanssa yhtä poikkeusta lukuun ottamatta.

Komentoriviargumentti --crop on lisätty. Kun tälle argumentille annetaan päätelaitteessa 1, menemme eteenpäin ja suoritamme rajaushakkimme.

Seuraavassa vaiheessa aloitamme lisätoiminnallisuuden toteuttamisen:

# if the status is '0', then OpenCV successfully performed image# stitchingif status == 0:# check to see if we supposed to crop out the largest rectangular# region from the stitched imageif args > 0:# create a 10 pixel border surrounding the stitched imageprint(" cropping...")stitched = cv2.copyMakeBorder(stitched, 10, 10, 10, 10,cv2.BORDER_CONSTANT, (0, 0, 0))# convert the stitched image to grayscale and threshold it# such that all pixels greater than zero are set to 255# (foreground) while all others remain 0 (background)gray = cv2.cvtColor(stitched, cv2.COLOR_BGR2GRAY)thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)

Huomaa, kuinka olen tehnyt riville 40 uuden lohkon sitä varten, kun --crop-lippu on asetettu. Aloitetaan tämän lohkon läpikäyminen:

  • Aluksi lisäämme 10 pikselin rajan stitched-kuvamme kaikille sivuille (rivit 43 ja 44) varmistaaksemme, että pystymme löytämään koko panoraamakuvan ääriviivat myöhemmin tässä osassa.
  • Sitten luomme gray-version stitched-kuvastamme (rivi 49).
  • Ja siitä rajaamme gray-kuvan (rivi 50).

Tässä on näiden kolmen vaiheen tulos (thresh ):

Kuva 6: Kynnysarvon määrittämisen jälkeen meille esitetään tämä kynnysarvonaamio, jossa korostetaan, missä OpenCV:n ommeltu + poimittu kuva sijaitsee.

Meillä on nyt panoraamastamme binäärikuva, jossa valkoiset pikselit (255) ovat etuala ja mustat pikselit (0) ovat tausta.

Kynnyskorjatun kuvamme perusteella voimme soveltaa ääriviivojen louhintaa, laskea suurimman ääriviivan rajaavan laatikon (esim, itse panoraamakuvan ääriviivat), ja piirtää rajaavan laatikon:

# find all external contours in the threshold image then find# the *largest* contour which will be the contour/outline of# the stitched imagecnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)c = max(cnts, key=cv2.contourArea)# allocate memory for the mask which will contain the# rectangular bounding box of the stitched image regionmask = np.zeros(thresh.shape, dtype="uint8")(x, y, w, h) = cv2.boundingRect(c)cv2.rectangle(mask, (x, y), (x + w, y + h), 255, -1)

Kontuurit uutetaan ja jäsennetään riveillä 55-57. Rivillä 58 napataan sitten se ääriviiva, jolla on suurin pinta-ala (eli itse ommellun kuvan ääriviiva).

Huomaa: imutils.grab_contours-funktio on uusi imutils==0.5.2:ssa imutils==0.5.2 OpenCV 2.4:n, OpenCV 3:n ja OpenCV 4:n ja niiden erilaisten paluuesimerkkien mukauttamiseksi cv2.findContours:lle.

Rivillä 62 varataan muistia uudelle suorakulmaiselle maskillemme. Tämän jälkeen rivi 63 laskee suurimman ääriviivamme rajaavan laatikon. Käyttämällä rajaavan suorakulmion tietoja rivillä 64 piirrämme maskiimme kiinteän valkoisen suorakulmion.

Yllä olevan koodilohkon tuloste näyttäisi seuraavalta:

Kuva 7: Pienin suorakulmainen alue, johon koko OpenCV-panoraama mahtuu.

Tämä rajaava laatikko (bounding box) on pienin suorakulmion muotoinen alue, jonka sisälle koko panoraama mahtuu.

Nyt tulee yksi suurimmista hakkeroinneista, jonka olen koskaan koonnut blogikirjoitukseen:

# create two copies of the mask: one to serve as our actual# minimum rectangular region and another to serve as a counter# for how many pixels need to be removed to form the minimum# rectangular regionminRect = mask.copy()sub = mask.copy()# keep looping until there are no non-zero pixels left in the# subtracted imagewhile cv2.countNonZero(sub) > 0:# erode the minimum rectangular mask and then subtract# the thresholded image from the minimum rectangular mask# so we can count if there are any non-zero pixels leftminRect = cv2.erode(minRect, None)sub = cv2.subtract(minRect, thresh)

Riveillä 70 ja 71 luomme kaksi kopiota kuvastamme mask:

  1. Ensimmäistä maskia, minMask , pienennetään hitaasti, kunnes se mahtuu panoraaman sisäosaan (ks. kuvio 5 tämän jakson yläosassa).
  2. Toisen maskin, sub , avulla määritetään, onko tarpeen jatkaa minMask pienentämistä .

Rivillä 75 käynnistetään while-silmukka, joka jatkaa silmukointia, kunnes sub:ssä ei ole enää etualan pikseleitä .

Rivillä 79 suoritetaan eroosiomorfologinen operaatio, jolla pienennetään minRect:n kokoa.

Rivi 80 vähentää sitten thresh minRect:stä – kun minRect:ssä ei ole enää etualan pikseleitä, voimme keskeyttää silmukan.

Olen lisännyt alla animaation hakkeroinnista:

Kuva 8: Animaatio hakkeroinnista, jonka keksin poimia OpenCV:n panoraamakuvasta minRect-alueen, jolloin saadaan esteettisesti miellyttävä ommeltu kuva

Ylhäällä on sub-kuvamme ja alhaalla minRect-kuvamme.

Huomaa, kuinka minRect:n kokoa pienennetään asteittain, kunnes sub:ssä ei ole enää yhtään etualan pikseliä jäljellä – tässä vaiheessa tiedämme, että olemme löytäneet pienimmän suorakulmaisen maskin, joka mahtuu panoraaman suurimmalle suorakulmaiselle alueelle.

Valittuamme pienimmän sisäisen suorakulmion voimme jälleen löytää ääriviivat ja laskea rajaavan laatikon, mutta tällä kertaa yksinkertaisesti poimimme ROI:n stitched kuvasta:

# find contours in the minimum rectangular mask and then# extract the bounding box (x, y)-coordinatescnts = cv2.findContours(minRect.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)c = max(cnts, key=cv2.contourArea)(x, y, w, h) = cv2.boundingRect(c)# use the bounding box coordinates to extract the our final# stitched imagestitched = stitched

Tässä meillä on:

  • Löytyneet ääriviivat minRect:ssä (rivit 84 ja 85).
  • Käsitelty ääriviivojen jäsentelyä useammalle OpenCV:n eri versiolle (linja 86). Tarvitset imutils>=0.5.2 käyttääksesi tätä funktiota.
  • Grabbasit suurimman ääriviivan (rivi 87).
  • Laskit suurimman ääriviivan rajauslaatikon (rivi 88).
  • Extraktoit ROI:n stitched:stä käyttäen rajauslaatikkotietoja (rivi 92).

Viimeinen stitched-kuva voidaan näyttää näytöllemme ja sitten tallentaa levylle:

# write the output stitched image to diskcv2.imwrite(args, stitched)# display the output stitched image to our screencv2.imshow("Stitched", stitched)cv2.waitKey(0)# otherwise the stitching failed, likely due to not enough keypoints)# being detectedelse:print(" image stitching failed ({})".format(status))

Rivit 95-99 hoitavat kuvan tallentamisen ja näyttämisen riippumatta siitä, onko rajaushakkimme suoritettu vai ei.

Aivan kuten aiemminkin, jos status-merkki ei palannut menestyksekkäästi, tulostamme virheviestin (rivit 103 ja 104).

Mennään eteenpäin ja tarkastellaan parannetun kuvien ompelun + OpenCV-putken tuloksia.

Parannetun kuvien ompelun tulokset

Varmista jälleen, että olet käyttänyt tämän päivän opetusohjelman ”Lataukset”-osiota ladataksesi lähdekoodin ja esimerkkikuvat.

Avaa sieltä terminaali ja suorita seuraava komento:

$ python image_stitching.py --images images/scottsdale --output output.png \--crop 1 loading images... stitching images... cropping...
Kuva 8: OpenCV:llä ja Pythonilla suorittamamme useiden kuvien ompelun tulos.

Huomaa, että tällä kertaa olemme poistaneet mustat alueet ommelluista tulostekuvista (jotka johtuvat vääristymismuunnoksista) soveltamalla yllä olevassa osiossa yksityiskohtaisesti kuvattua hakkerointiamme.

Limiitit ja haitat

Edellisessä opetusohjelmassa esittelin, miten voit rakentaa reaaliaikaisen panoraama- ja kuvien ompelualgoritmin – tämä opetusohjelma oli riippuvainen siitä, että suoritimme manuaalisesti avainpisteiden havaitsemisen, ominaisuuksien louhinnan ja avainpisteiden täsmäytyksen, jolloin pääsimme käsiksi homografiamatriisiin, jota käytimme kahden syöttökuvamme loimuttamiseen panoraamaksi.

Ja vaikka OpenCV:n sisäänrakennetut cv2.createStitcher– ja cv2.Stitcher_create-funktiot pystyvätkin varmasti rakentamaan tarkkoja ja esteettisesti miellyttäviä panoraamoja, yksi menetelmän ensisijaisista haittapuolista on se, että se abstrahoi kaiken pääsyn homografiamatriiseihin.

Yksi reaaliaikaisen panoraamakuvan rakentamisen olettamuksista on se, että kohtaus itsessään ei sisällöltään muutu paljon.

Kun olemme laskeneet alkuperäisen homografia-estimoinnin, meidän pitäisi joutua vain satunnaisesti laskemaan matriisi uudelleen.

Ei meidän tarvitse suorittaa täysimittaista avainpisteiden täsmäytystä ja RANSAC-estimointia, se antaa meille valtavan nopeuslisäyksen panoraamakuvan rakentamiseen.

Ilman pääsyä käsiksi raakoihin homografiamatriiseihin olisi haastavaa ottaa OpenCV:n sisäänrakennettu kuvien ompelualgoritmi mukaan ja konvertoida se reaaliaikaiseen käyttöön.

Kohtaat virheitä suorittaessasi kuvan ompelua OpenCV:llä?

On mahdollista, että kohtaat virheitä yrittäessäsi käyttää joko cv2.createStitcher-funktiota tai cv2.Stitcher_create-funktioita.

Kaksi ”helposti ratkaistavaa” virhettä, joihin näen ihmisten törmäävän, on se, että he unohtavat, mitä OpenCV:n versiota he käyttävät.

Jos esimerkiksi käytät OpenCV 4:ää, mutta yrität kutsua cv2.createSticher-funktiota, saat seuraavan virheilmoituksen:

>>> cv2.createStitcherTraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: module 'cv2' has no attribute 'createStitcher'

Sinun pitäisi sen sijaan käyttää cv2.Stitcher_create-funktiota.

Viisinkertaisesti, jos käytät OpenCV 3:aa ja yrität kutsua cv2.Sticher_create-funktiota, saat tämän virheilmoituksen:

>>> cv2.Stitcher_createTraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: module 'cv2' has no attribute 'Stitcher_create'

Käyttäkää sen sijaan cv2.createSticher-funktiota.

Jos et ole varma, mitä OpenCV-versiota käytät, voit tarkistaa käyttämällä cv2.__version__ :

>>> cv2.__version__'4.0.0'

Tässä näet, että käytän OpenCV 4.0.0.

Voit tehdä saman tarkistuksen järjestelmässäsi.

Viimeinen virhe, johon voit törmätä, ja luultavasti yleisin, liittyy siihen, että OpenCV:llä (1) ei ole contrib-tukea ja (2) se on käännetty ilman, että OPENCV_ENABLE_NONFREE=ON-optio on käytössä.

Voidaksesi ratkaista tämän virheen sinun on asennettava opencv_contrib-moduulit sekä asetettava OPENCV_ENABLE_NONFREE-vaihtoehto ON:ksi.

Jos kohtaat OpenCV:n non-free- ja contrib-moduuleihin liittyvää virhettä, varmista OpenCV:n täydellisen asennuksen varmistaminen OpenCV:n asennusoppaideni avulla.

Huomaa: Huomaa, etten voi auttaa vianmäärityksessä omassa OpenCV-asennuksessasi, jos et ole noudattanut jotakin asennusoppaistani, joten varmista, että käytät OpenCV-asennusoppaitani, kun konfiguroit järjestelmääsi.

Yhteenveto

Tämänpäiväisessä opetusohjelmassa opit suorittamaan useiden kuvien stitchauksen OpenCV:n ja Pythonin avulla.

Käyttämällä sekä OpenCV:tä että Pythonia pystyimme ompelemaan useita kuvia yhteen ja luomaan panoraamakuvia.

Tulostamamme panoraamakuvat eivät olleet ainoastaan tarkkoja ompelusijoitukseltaan, vaan myös esteettisesti miellyttäviä.

Yksi OpenCV:n sisäänrakennetun kuvien ompelemisluokan käytön suurimmista haittapuolista on kuitenkin se, että se abstrahoi suuren osan sisäisestä laskennasta, mukaan lukien itse tuloksena olevat homografiamatriisit.

Jos yrität suorittaa reaaliaikaista kuvien ompelemista, kuten teimme aiemmassa postauksessamme, saatat kokea, että on hyödyllistä välimuistiin tallettaa homografiamatriisi ja suorittaa avainpisteiden havaitseminen, ominaisuuksien louhinta ja ominaisuuksien yhteensovittaminen vain satunnaisesti.

Tämä vaiheiden ohittaminen ja välimuistissa olevan matriisin käyttäminen perspektiivin loimennuksen suorittamiseen voi vähentää putkistosi laskennallista taakkaa ja viime kädessä nopeuttaa reaaliaikaista kuvan ompelualgoritmia, mutta valitettavasti OpenCV:n cv2.createStitcher Python-sidonnaiset cv2.createStitcher eivät anna meille pääsyä raakamatriiseihin.

Jos olet kiinnostunut oppimaan lisää reaaliaikaisesta panoraamojen rakentamisesta, lue edellinen postaukseni.

Toivottavasti nautit tämänpäiväisestä tutoriaalista kuvien ompelemisesta!

Lataaksesi tämänpäiväisen postauksen lähdekoodin ja saadaksesi ilmoituksen siitä, että tutoriaalit julkaistaan täällä PyImageSearchin sivuilla, kirjoita sähköpostiosoitteesi alla olevalle lomakkeelle!

Vastaa

Sähköpostiosoitettasi ei julkaista.