socialgekon.com
  • Tärkein
  • Projektinhallinta
  • Trendit
  • Työkalut Ja Oppaat
  • Web-Käyttöliittymä
Teknologia

Johdanto Python-kuvankäsittelyyn laskennallisessa valokuvauksessa

Laskennallinen valokuvaus on valokuvausprosessin tehostamista laskennalla. Vaikka yleensä ajattelemme, että tämä koskee vain lopputuloksen jälkikäsittelyä (samanlainen kuin valokuvien muokkaus), mahdollisuudet ovat paljon laajemmat, koska laskenta voidaan ottaa käyttöön valokuvauksen jokaisessa vaiheessa - aloittaen kohtauksen valaistuksesta, jatkamalla objektiivissa ja lopulta jopa otetun kuvan näytöllä.

Tämä on tärkeää, koska sen avulla voidaan tehdä paljon enemmän ja eri tavoin kuin mitä normaalilla kameralla voidaan saavuttaa. Se on myös tärkeä, koska nykyisin yleisin kameratyyppi - mobiilikamera - ei ole erityisen tehokas verrattuna isompaan sisarukseensa (DSLR), mutta onnistuu kuitenkin tekemään hyvää työtä hyödyntämällä laitteessa olevaa laskentatehoa .

Tarkastelemme kahta esimerkkiä, joissa laskenta voi parantaa valokuvausta - tarkemmin sanottuna näemme, kuinka yksinkertaisesti useampien kuvien ottaminen ja vähän Pythonia käyttämällä niiden yhdistäminen voi luoda hienoja tuloksia kahdessa tilanteessa, jossa mobiilikameralaitteisto ei todella loistaa - heikko valo ja korkea dynaaminen alue.



Hämärässä valokuvaus

Oletetaan, että haluamme ottaa kuvan heikossa valossa, mutta kameralla on pieni aukko (linssi) ja rajoitettu valotusaika. Tämä on tyypillinen tilanne matkapuhelinkameroille, jotka heikossa valaistuksessa voivat tuottaa tällaisen kuvan (otettu iPhone 6 -kameralla):

Kuva parista lelusta heikossa valaistuksessa

Jos yritämme parantaa kontrastia, tulos on seuraava, mikä on myös melko huono:

Sama kuva kuin yllä, paljon kirkkaampi, mutta häiritsevällä visuaalisella kohinalla

Mitä tapahtuu? Mistä kaikki tämä melu tulee?

Vastaus on, että melu tulee anturista - laitteesta, joka yrittää selvittää, milloin valo osuu siihen ja kuinka voimakas valo on. Heikossa valossa sen on kuitenkin lisättävä herkkyyttään paljon rekisteröidäkseen mitään, ja tämä korkea herkkyys tarkoittaa, että se alkaa myös havaita vääriä positiivisia - fotoneja, joita yksinkertaisesti ei ole. (Lisähuomautuksena tämä ongelma ei koske vain laitteita, vaan myös meitä ihmisiä: Kun seuraavan kerran olet pimeässä huoneessa, huomaa näkökentässäsi oleva ääni.)

Kuvantamislaitteessa on aina jonkin verran melua; kuitenkin, jos signaalilla (hyödyllinen tieto) on korkea intensiteetti, kohina on merkityksetön (korkea signaali-kohinasuhde). Kun signaali on heikko - kuten hämärässä - melu erottuu (matala signaali kohinaan).

Silti voimme voittaa meluongelman jopa kaikilla kamerarajoituksilla saadaksemme parempia kuvia kuin yllä oleva.

Tätä varten meidän on otettava huomioon, mitä tapahtuu ajan myötä: Signaali pysyy samana (sama kohtaus ja oletamme sen olevan staattinen), kun taas melu on täysin satunnainen. Tämä tarkoittaa, että jos otamme useita otoksia näkymästä, heillä on eri versiot melusta, mutta samat hyödylliset tiedot.

Joten, jos keskiarvo on useita ajan mittaan otettuja kuvia, kohina poistuu, kun signaali ei muutu.

Seuraava kuva esittää yksinkertaistetun esimerkin: Meillä on signaali (kolmio), johon kohina vaikuttaa, ja yritämme palauttaa signaalin keskiarvolla useita saman signaalin esiintymiä, joihin eri kohina vaikuttaa.

Neljän paneelin esitys kolmiosta, hajautettu kuva, joka edustaa kolmiota, johon on lisätty kohinaa, eräänlainen rosoinen kolmio, joka edustaa 50 esiintymän keskiarvoa ja 1000 esiintymän keskiarvoa, joka näyttää lähes identtiseltä alkuperäisen kolmion kanssa.

Näemme, että vaikka kohina on riittävän voimakas vääristämään signaalia kokonaan missä tahansa yksittäisessä tapauksessa, keskiarvo laskee asteittain ja palautamme alkuperäisen signaalin.

Katsotaanpa, miten tämä periaate soveltuu kuviin: Ensinnäkin meidän on otettava useita kuvia kohteesta mahdollisimman suurella valotuksella, jonka kamera sallii. Saat parhaat tulokset käyttämällä sovellusta, joka sallii manuaalisen kuvaamisen. On tärkeää, että kuvat otetaan samasta paikasta, joten (improvisoitu) jalusta auttaa.

Enemmän kuvia tarkoittaa yleensä parempaa laatua, mutta tarkka määrä riippuu tilanteesta: kuinka paljon valoa on, kuinka herkkä kamera on jne. Hyvä etäisyys voi olla missä tahansa välillä 10 ja 100.

Kun meillä on nämä kuvat (raakamuodossa, jos mahdollista), voimme lukea ja käsitellä niitä Pythonissa.

Niille, jotka eivät ole perehtyneet kuvankäsittelyyn Pythonissa, meidän on mainittava, että kuva on 2D-tavuarvojen taulukko (0-255) - siis yksivärinen tai harmaasävykuva. Värikuvan voidaan ajatella olevan kolmen tällaisen kuvan joukko, yksi kullekin värikanavalle (R, G, B), tai käytännössä 3D-ryhmä, joka on indeksoitu pystysuoran sijainnin, vaakasuoran sijainnin ja värikanavan (0, 1, 2) mukaan .

Käytämme kahta kirjastoa: NumPy ( http://www.numpy.org/ ) ja OpenCV ( https://opencv.org/ ). Ensimmäisen avulla voimme suorittaa laskutoimituksia taulukoista erittäin tehokkaasti (yllättävän lyhyellä koodilla), kun taas OpenCV käsittelee tässä tapauksessa kuvatiedostojen lukemista / kirjoittamista, mutta on paljon kykenevämpi tarjoamaan monia kehittyneitä grafiikkamenettelyjä - joista joitain aiomme käytä myöhemmin artikkelissa.

import os import numpy as np import cv2 folder = 'source_folder' # We get all the image files from the source folder files = list([os.path.join(folder, f) for f in os.listdir(folder)]) # We compute the average by adding up the images # Start from an explicitly set as floating point, in order to force the # conversion of the 8-bit values from the images, which would otherwise overflow average = cv2.imread(files[0]).astype(np.float) for file in files[1:]: image = cv2.imread(file) # NumPy adds two images element wise, so pixel by pixel / channel by channel average += image # Divide by count (again each pixel/channel is divided) average /= len(files) # Normalize the image, to spread the pixel intensities across 0..255 # This will brighten the image without losing information output = cv2.normalize(average, None, 0, 255, cv2.NORM_MINMAX) # Save the output cv2.imwrite('output.png', output)

Tulos (automaattikontrastilla) osoittaa, että kohina on kadonnut, mikä on erittäin suuri parannus alkuperäiseen kuvaan.

Alkuperäinen valokuva leluista, tällä kertaa sekä kirkkaampi että paljon selkeämpi, ja siinä on hyvin vähän havaittavaa melua

Huomaa kuitenkin edelleen joitain outoja esineitä, kuten vihertävä kehys ja ristikkomainen kuvio. Tällä kertaa se ei ole satunnainen, vaan kiinteä kuvamelu. Mitä tapahtui?

Lähikuva yllä olevan kuvan vasemmassa yläkulmassa

Lähikuva vasemmassa yläkulmassa, jossa näkyy vihreä kehys ja ruudukkokuvio

Jälleen voimme syyttää sitä anturista. Tässä tapauksessa havaitaan, että anturin eri osat reagoivat valoon eri tavoin, mikä johtaa näkyvään kuvioon. Jotkut näiden kuvioiden elementit ovat säännöllisiä ja liittyvät todennäköisesti anturisubstraattiin (metalli / pii) ja siihen, miten se heijastaa / absorboi saapuvia fotoneja. Muut elementit, kuten valkoinen pikseli, ovat yksinkertaisesti viallisia anturipikseleitä, jotka voivat olla liian herkkiä tai liian herkkiä valolle.

Onneksi on myös tapa päästä eroon tällaisesta melusta. Sitä kutsutaan tumman kehyksen vähennys .

Tätä varten tarvitsemme kuvan itse kuvakohinasta, ja tämä voidaan saada, jos valokuvaamme pimeyttä. Kyllä, se on oikein - peitä vain kameran reikä ja ota paljon kuvia (esimerkiksi 100), joissa on suurin valotusaika ja ISO-arvo, ja käsittele niitä yllä kuvatulla tavalla.

Kun keskiarvo mitataan useista mustista kehyksistä (jotka eivät itse asiassa ole mustia satunnaisen kohinan vuoksi), päädymme kiinteään kuvameluun. Voimme olettaa, että tämä kiinteä kohina pysyy vakiona, joten tätä vaihetta tarvitaan vain kerran: Tuloksena olevaa kuvaa voidaan käyttää uudelleen kaikissa tulevissa heikossa valossa otettavissa kuvissa.

Näin kuvion kohinan oikeassa yläkulmassa (kontrastisäätö) näyttää olevan iPhone 6: lle:

Kuvion kohina edellisessä kuvassa näytetylle kehyksen osalle

Jälleen huomaamme ruudukon kaltaisen tekstuurin ja jopa sen, joka näyttää olevan jumissa oleva valkoinen pikseli.

Kun meillä on tämän tumman kehyskohinan arvo (average_noise -muuttujassa), voimme yksinkertaisesti vähentää sen tähänastisesta laukauksestamme ennen normalisointia:

average -= average_noise output = cv2.normalize(average, None, 0, 255, cv2.NORM_MINMAX) cv2.imwrite('output.png', output)

Tässä on viimeinen valokuvamme:

Yksi kuva valokuvasta, tällä kertaa ilman mitään todisteita siitä, että se olisi otettu hämärässä

Suuri dynaaminen alue

Toinen pienen (mobiilikameran) rajoitus on sen pieni dynaaminen alue, mikä tarkoittaa, että valon voimakkuuksien alue, jolla se voi siepata yksityiskohtia, on melko pieni.

Toisin sanoen kamera pystyy sieppaamaan vain kapean kaistan valon voimakkuuksista kohtauksesta; kyseisen kaistan alapuolella olevat voimakkuudet näyttävät puhtaalta mustalta, kun taas sen yläpuoliset voimakkuudet näyttävät puhtaalta valkoiselta, ja kaikki yksityiskohdat menetetään näiltä alueilta.

On kuitenkin temppu, jota kamera (tai valokuvaaja) voi käyttää - ja se on valotusajan (aika, jonka anturi altistuu valolle) säätäminen anturiin saapuvan valon kokonaismäärän hallitsemiseksi tehokkaasti vaihtamalla aluetta ylös tai alas tietyn kohtauksen sopivimman alueen kaappaamiseksi.

Mutta tämä on kompromissi. Monista yksityiskohdista ei pääse lopulliseen valokuvaan. Kahdessa alla olevassa kuvassa näkyy sama kohtaus, joka on kuvattu eri valotusajoilla: hyvin lyhyt valotus (1/1000 s), keskisuuri valotus (1/50 s) ja pitkä valotus (1/4 s).

Kolme versiota samasta kukkakuvasta, yksi niin tumma, että suurin osa valokuvasta on musta, yksi normaalin näköinen, vaikkakin hieman valitettavalla valaistuksella, ja kolmas valo, jota pyöritetään niin korkealle, että se

Kuten näette, kumpikaan kolmesta kuvasta ei pysty sieppaamaan kaikkia käytettävissä olevia yksityiskohtia: Lampun hehkulanka näkyy vain ensimmäisessä otoksessa ja osa kukan yksityiskohdista näkyy joko keskellä tai viimeisessä otoksessa, mutta ei molemmat.

Hyvä uutinen on, että voimme tehdä asialle jotain, ja jälleen kerran siihen liittyy useiden kuvien rakentaminen pienellä Python-koodilla.

Lähestymistapa perustuu Paul Debevecin ym. Työhön, joka kuvaa menetelmää artikkelissaan tässä . Menetelmä toimii näin:

Ensinnäkin se vaatii useita otoksia samasta kohtauksesta (paikallaan), mutta eri valotusajoilla. Jälleen, kuten edellisessä tapauksessa, tarvitsemme jalustan tai tuen varmistaaksemme, että kamera ei liiku ollenkaan. Tarvitsemme myös manuaalisen kuvausohjelman (jos käytät puhelinta), jotta voimme hallita valotusaikaa ja estää kameran automaattiset säädöt. Vaadittujen kuvien määrä riippuu kuvassa olevien voimakkuuksien alueesta (kolmesta ylöspäin), ja valotusajat tulisi sijoittaa kyseisen alueen yli siten, että haluamamme yksityiskohdat näkyvät selvästi ainakin yhdessä kuvassa.

Seuraavaksi algoritmia käytetään rekonstruoimaan kameran vastekäyrä samojen pikselien värin perusteella eri valotusajoissa. Tämän avulla voimme periaatteessa luoda kartan pisteen todellisen kohtauksen kirkkauden, valotusajan ja arvon välillä, jonka vastaavalla pikselillä on otetussa kuvassa. Käytämme Debevecin menetelmän toteutusta OpenCV-kirjastosta.

# Read all the files with OpenCV files = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg'] images = list([cv2.imread(f) for f in files]) # Compute the exposure times in seconds exposures = np.float32([1. / t for t in [1000, 500, 100, 50, 10]]) # Compute the response curve calibration = cv2.createCalibrateDebevec() response = calibration.process(images, exposures)

Vastekäyrä näyttää tältä:

Kaavio, joka näyttää vastekäyrän pikselialtistuksena (loki) pikseliarvon yli

Pystyakselilla meillä on pisteen kohtauksen kirkkauden ja valotusajan kumulatiivinen vaikutus, kun taas vaaka-akselilla meillä on vastaavan pikselin arvo (0-255 kanavaa kohti).

Tämän käyrän avulla voimme suorittaa käänteisen toiminnan (joka on prosessin seuraava vaihe) - pikseliarvon ja valotusajan perusteella voimme laskea kunkin kohtauksen todellisen kirkkauden. Tätä kirkkausarvoa kutsutaan säteilyksi ja se mittaa valoenergian määrää, joka putoaa anturin pinta-alayksikköön. Toisin kuin kuvadata, se esitetään liukulukujen avulla, koska se heijastaa paljon laajempaa arvoja (siis korkea dynaaminen alue). Kun meillä on irradianssikuva (HDR-kuva), voimme yksinkertaisesti tallentaa sen:

# Compute the HDR image merge = cv2.createMergeDebevec() hdr = merge.process(images, exposures, response) # Save it to disk cv2.imwrite('hdr_image.hdr', hdr)

Niille meistä, jotka ovat onnekkaita saamaan HDR-näytön (joka on yhä yleisempää), voi olla mahdollista visualisoida tämä kuva suoraan kaikessa loistossaan. Valitettavasti HDR-standardit ovat vielä lapsenkengissään, joten prosessi siihen voi olla hieman erilainen eri näytöissä.

Meille muille hyvä uutinen on, että voimme silti hyödyntää näitä tietoja, vaikka normaali näyttö edellyttää, että kuvalla on tavuarvokanavia (0–255). Vaikka meidän on luovuttava joistakin säteilykartan rikkauksista, meillä on ainakin mahdollisuus hallita, miten se tehdään.

Tätä prosessia kutsutaan sävykartoitus ja siihen kuuluu kelluvan pisteen säteilykartan muuntaminen (suurella arvoalueella) vakiotavuarvokuvaksi. On tekniikoita tehdä niin, että monet ylimääräiset yksityiskohdat säilyvät. Kuvittele vain, että annat sinulle esimerkin siitä, miten tämä voi toimia, ennen kuin puristamme liukuluku-alueen tavuarvoiksi, parannamme (terävöitämme) HDR-kuvassa olevia reunoja. Näiden reunojen parantaminen auttaa säilyttämään ne (ja implisiittisesti niiden tarjoaman yksityiskohdan) myös matalan dynaamisen alueen kuvassa.

OpenCV tarjoaa joukon näistä sävykartoitusoperaattoreista, kuten Drago, Durand, Mantiuk tai Reinhardt. Tässä on esimerkki siitä, miten yhtä näistä operaattoreista (Durand) voidaan käyttää ja mitä se tuottaa.

durand = cv2.createTonemapDurand(gamma=2.5) ldr = durand.process(hdr) # Tonemap operators create floating point images with values in the 0..1 range # This is why we multiply the image with 255 before saving cv2.imwrite('durand_image.png', ldr * 255)

Yllä olevan laskennan tulos näytetään kuvana

Pythonin avulla voit myös luoda omia operaattoreita, jos tarvitset enemmän prosessin hallintaa. Tämä on esimerkiksi tulos, joka on saatu mukautetulla operaattorilla, joka poistaa hyvin muutamissa pikseleissä esitetyt intensiteetit ennen kuin kutistuu arvoalue 8 bittiin (jota seuraa automaattisen kontrastin vaihe):

Kuva, joka syntyy yllä olevan prosessin seuraamisesta

Ja tässä on yllä olevan operaattorin koodi:

def countTonemap(hdr, min_fraction=0.0005): counts, ranges = np.histogram(hdr, 256) min_count = min_fraction * hdr.size delta_range = ranges[1] - ranges[0] image = hdr.copy() for i in range(len(counts)): if counts[i] = ranges[i + 1]] -= delta_range ranges -= delta_range return cv2.normalize(image, None, 0, 1, cv2.NORM_MINMAX)

Johtopäätös

Olemme nähneet, kuinka pienellä Pythonilla ja parilla tukevalla kirjastolla voimme siirtää fyysisen kameran rajoja lopputuloksen parantamiseksi. Molemmat keskustelemamme esimerkit käyttävät useita huonolaatuisia otoksia luomaan jotain parempaa, mutta on olemassa monia muita lähestymistapoja erilaisiin ongelmiin ja rajoituksiin.

Vaikka monissa kamerapuhelimissa on tallennettuja tai sisäänrakennettuja sovelluksia, jotka vastaavat näihin esimerkkeihin, ei ole selvästikään lainkaan vaikeaa ohjelmoida niitä käsin ja nauttia korkeammasta hallinnasta ja ymmärryksestä, joka voidaan saada.

Jos olet kiinnostunut kuvan laskemisesta mobiililaitteella, tarkista OpenCV-opetusohjelma: Reaaliaikainen objektitunnistus MSER: n avulla iOS: ssä ApeeScapeer ja eliitti OpenCV-kehittäjä Altaibayar Tseveenbayar.

Perustietojen ymmärtäminen

Kuinka kameran anturi toimii?

Anturi muuntaa tulevan valon sähköisiksi signaaleiksi, jotka sitten vahvistetaan ja digitoidaan. Sen pinta on jaettu pikseleihin, jotka jaetaan edelleen kanaviin. Siksi anturi tuottaa kolme numeroa, jotka vastaavat punaista, vihreää ja sinistä valovoimaa jokaiselle kohtauksen kohdalle.

Mitä kuvankäsittely tarkoittaa?

Kuvankäsittely viittaa kaikkiin laskennan vaiheisiin, jotka suoritetaan sen jälkeen, kun anturi on kaapannut raakakuvan sen parantamiseksi tai muokkaamiseksi.

Kuinka kuvankäsittely toimii?

Kuvankäsittely tapahtuu ohjelmistossa soveltamalla numeerisia toimintoja kuvadataan. Yleisimmillä kuvankäsittelytekniikoilla on vankka matemaattinen tausta.

Mikä on Python, NumPy ja OpenCV?

Python on ohjelmointikieli, joka soveltuu hyvin tieteelliseen laskentaan. NumPy on Python-kirjasto, joka yksinkertaistaa matriisien numeeristen operaatioiden tekemistä. OpenCV on erikoistunut kirjasto, joka keskittyy kuvankäsittelyyn ja tietokonenäköön.

Miksi hyvin hämärässä olevat valokuvat ovat meluisia?

Hämärässä ja rajoitetulla valotuksella anturiin putoaa hyvin pieni määrä valoenergiaa. Anturi yrittää kompensoida vahvistamalla signaalia, mutta päätyy myös vahvistamaan omaa sähköistä kohinaa.

Mitä HDR-valokuvaus on?

Suuren dynaamisen alueen (HDR) valokuvaus viittaa fyysisen valon voimakkuuden sieppaamiseen näkymässä. Perinteinen digitaalinen valokuvaus käyttää vain vähän intensiteettitasoja (tyypillisesti 256).

Mikä on sävykartoitus?

Sävykartoitus on tekniikka, joka muuntaa HDR-kuvan tavanomaiseksi kuvaksi säilyttäen suurimman osan yksityiskohdista, jotta kuva voidaan näyttää muulla kuin HDR-näytöllä.

Sivunopeus 101: Säätiö mobiilikäyttöliittymäsuunnittelijoille

Mobiilisuunnittelu

Sivunopeus 101: Säätiö mobiilikäyttöliittymäsuunnittelijoille
Suunnittelu ihmisen käyttäytymiseen: Aineettoman määritteleminen

Suunnittelu ihmisen käyttäytymiseen: Aineettoman määritteleminen

Ux-Suunnittelu

Suosittu Viestiä
Onko Yhdysvaltain oman pääoman joukkorahoitusmarkkinat eläneet odotuksia?
Onko Yhdysvaltain oman pääoman joukkorahoitusmarkkinat eläneet odotuksia?
Fintech-teollisuuden tila (infografiikan kanssa)
Fintech-teollisuuden tila (infografiikan kanssa)
10 Yleisimmät verkkoturvan haavoittuvuudet
10 Yleisimmät verkkoturvan haavoittuvuudet
Kuka tiesi Adobe CC: n voivan kehystää?
Kuka tiesi Adobe CC: n voivan kehystää?
Opas UTF-8-koodaukseen PHP: ssä ja MySQL: ssä
Opas UTF-8-koodaukseen PHP: ssä ja MySQL: ssä
 
Fintech ja pankit: Kuinka pankkisektori voi reagoida häiriöiden uhkaan?
Fintech ja pankit: Kuinka pankkisektori voi reagoida häiriöiden uhkaan?
Shopify-suunnitteluvinkit ja UX: n parhaat käytännöt
Shopify-suunnitteluvinkit ja UX: n parhaat käytännöt
Suorita matematiikka: Mikropalvelusovellusten skaalaus orkesterin kanssa
Suorita matematiikka: Mikropalvelusovellusten skaalaus orkesterin kanssa
Aloittelijan opas vedenalaiseen valokuvaukseen iPhonella
Aloittelijan opas vedenalaiseen valokuvaukseen iPhonella
Motivaation säännöt: Tarina epäonnistuneiden myyntikannustinjärjestelmien korjaamisesta
Motivaation säännöt: Tarina epäonnistuneiden myyntikannustinjärjestelmien korjaamisesta
Luokat
Tuotemerkin SuunnitteluWeb-KäyttöliittymäVarastointiKetterä KykyLähettäminenIhmiset Ja JoukkueetSijoittajat Ja RahoitusTuotteen ElinkaariProsessi Ja TyökalutLiikevaihdon Kasvu

© 2023 | Kaikki Oikeudet Pidätetään

socialgekon.com