Kokeillaan tällä kertaa maskien käyttöä. Maski on harmaasävykuva, jolla voidaan rajata kuvista mielivaltaisia alueita. Käytän tässä maskina tätä kuvaa. Huomaa, että maskin ei tarvitse olla joko/tai, vaan sävyjen avulla voidaan myös tehdä esim. pehmeitä siirtymiä kuvasta toiseen.
Luetaan tuo maski ja muunnetaan se tällä kertaa liukuluvuiksi välillä 0..1. Muutenkin tehdään laskutoimitukset nyt liukuluvuilla, jottei 255-leikkuri pääse nyt sotkemaan. Ja samantien kannattaa muistaa sekin, että tuon leikkurin aiheuttamat sivuvaikutukset ovat usein efekteinä mielenkiintoisia. Ja sitten hommiin, ensin tarvitsemme numpy-kirjaston jonka otamme käyttöön lyhennetyllä nimellä np.
>>> import numpy as np >>> mask = cv2.imread("test2mask.png") >>> mask = mask.astype(np.float32)/255 >>> mask.min() 0.0 >>> mask.max() 0.99215686
Luemme sitten jo tutun kuvan levyltä. Huomaamme että maski ja kuva ovat eri kokoiset, skaalamme maskin samaan kokoon kuin kuva. Sitten kerromme kuvan maskilla, lopputuloksena saadaan kuva jossa maskin tummat kohdat ovat tummia ja maskin vaaleissa osissa näkyy alkuperäinen kuva. Miksi? Meillä on nyt maski, jossa musta on 0 ja valkoinen 1, ja sillä me kerromme kaikki pikselit.
>>> im = cv2.imread("test4.png") >>> im.shape (480, 640, 3) >>> mask.shape (595, 841, 3) >>> mask2 = cv2.resize(mask, (640, 480)) >>> mask2.shape (480, 640, 3) >>> out = mask2 * im.astype(np.float32) >>> out.max() 245.40228 >>> cv2.imwrite("masked.png", out.astype(np.uint8)) True
Ja se toimi. Huomaa, että muunnimme lopputuloksen tuossa kokonaisluvuksi (n p.uint8) ennen tallennusta. Tämä siksi, että muuten opencv olettaa että koska arvot ovat liukulukuja, pikselien arvot ovat välillä 0..1. Siitäkin kyllä syntyy välillä jännä efekti.
Jos haluamme tuohon muun kuin mustan taustan, niin haetaan siihen toinen kuva, tehdään sille maskaus käänteisellä maskilla ja katsotaan ensin miltä se näyttää.
>>> bkg = cv2.imread("tausta.jpg") >>> bkg.shape (480, 640, 3) >>> mask2b = 1 - mask2 >>> out2 = mask2b * bkg.astype(np.float32) >>> cv2.imwrite("masked2.png", out2.astype(np.uint8)) True
Jep, eli nyt meillä on mustaa eli nollia siinä missä toisessa kuvassa on sisältöä, ja päinvastoin. Nyt meidän pitäisi voida aika turvallisesti summata nämä kaksi kuvaa ilman että 255-leikkuri iskee. Kokeillaan.
>>> out9 = out + out2 >>> cv2.imwrite("combined.png", out9) True
Ja tuloksena on kuin onkin kuva jossa maskin perusteella on yhdistetty etuala ja tausta eri kuvista. Ainakin itselleni ollut hyvin hyödyllistä tekniikkaa, mm. teoksessa Virtual vacation photos, joka oli esillä Pesula-galleriassa syyskuussa 2020 (alemmassa kuvassa oikealla).