Sissejuhatus pildiliste andmete töötlusse ja analüüsi 1.

Antud materjali koostamise eesmärgiks on leida viise, kuidas hinnata objektiivselt pilte ja neil olevat informatsiooni. Et tulemused oleksid mõõdetavad, võrreldavad ja neid saaks teostada automaatselt.

Töövahendite tutvustus

Jupyter märkmik

Jupyter notebook on veebipõhine interaktiivne keskkond, kus saab vaheldumisi kirjutada teksti ja käivitatavaid koodi (python) lahtreid. Et midagi arvutada, töödelda andmeid, kuvada graafikuid jne. Selle kasutamine on väga levinud andmeteadustes, masinõppes ja hariduses.

Colab on Google poolt majutatav Jupyter notebook.

Python

Python on üldotstarbeline programmeerimiskeel. Pythonit peetakse küllaltki lihtsaks keeleks, milles tavaliselt alustatakse programmeerimise õppimist. Kasutamise eeliseks on ka see, et on juba loodud väga palju valmis mooduleid ehk teeked (ingl. library) erinevate probleemide lahendamiseks. Näiteks Matplotlib graafikute loomiseks. NumPy suurte andmemassiivide töötlemiseks. PyTorch masinõppe jaoks. Tkinter graafiliste kasutajaliideste loomiseks ja palju muid.

Markdown

Teksti lahtrites olevat sisu saab kirjutada märgenduskeel Markdown abil. Selle abil saab lihtalt ja kiiresti kirjutada rikalikult vormindatud teksti.

Näiteks pealkirja loomiseks:

Mis on pilt?

Mis on pilt arvuti jaoks? Kuidas on pilt salvestatud arvutis? Kuidas arvutid näevad värve?

Nagu nimigi ütleb, arvutid arvutavad. Ja arvutada saab ainult numbritega. Kõik need YouTube videod, ajalehe artiklid ja kassi pildid on salvestatud arvutisse mingil kujul numbritena.

Kui me suurendame pilti sisse siis näeme, et see koosneb pisikestest ruutudest – pikslitest. Pilti võib vaadata, kui suurt mosaiiki, mis on kokku laotud pisikestest klotsidest. (Pilt 1)

Pikslid

Igas pikslis on kolm numbrit, mis kirjeldavad kolme värvi: punast, rohelist ja sinist. Neid kutsutakse RGB värvideks (Red, Green, Blue). Nendest piisab luua kõik värvitoonid, mida me ekraanil näeme. Iga number on salvestatud 8-bitise arvuna. See tähendab selle väärtus on 0 kuni 255-ni. Kokku 256 erinevat heleduse astet, kus 0 on must ja 255 on valge. Seda võib vaadata nii, et meil on kolme värvi tuled ja me saame muuta iga tule heledust. See number ütleb, kui intensiivne, mingi toon on. Kokku saab moodustada nii 16’777’216 värvitooni (256 * 256 * 256). (Pilt 2)

Värvijaotus halltoonides, punastes, rohelistes ja sinistes kanalites. Vasakul küljel on väärtus 0, paremal 255.

Nüüd võime pilti vaadata, kui ühte suurt Exceli tabelit, kus iga lahter on üks piksel. Tabeli laius ja kõrgus on pildi laius ja kõrgus. Meil on kahedimensiooniline tabel. Kuna ühes lahtris saame hoida ainult ühte arvu. Siis paneme RGB väärtused erinevatesse tabelitesse. Nii, et meil on üks tabeli kiht kus on punane (R), teine kus roheline (G) ja kolmandal sinine (B). Siia võib lisada ka neljanda läbipaistvuse (A), kui meil oleks png fail, mitte jpg. Neid nimetatakse kanaliteks ja mõelda võib neist, kui pildi kolmandast mõõtmest. (Pilt 3)

RGB kanalid

Neid numbreid saame me analüüsida ja teha nendega erinevaid arvutusi.

Näited

Impordime vajalikud teegid (Ing. Library).

import imageio                  # Piltide lugemiseks ja muutmiseks
import matplotlib.pyplot as plt # Skeemide koostamiseks
%matplotlib inline

Kuna kõik mu pildid on selles kataloogis salvestan selle eraldi muutujasse.

#Kõik pildid on siin kataloogis
kataloog = 'https://raw.githubusercontent.com/taunoe/jupyter-notebooks/main/Pildi-anal%C3%BC%C3%BCs/images/'

Kuvame pildi.

pilt = imageio.imread(kataloog + 'image.jpg')
plt.figure(figsize = (5,5))
plt.imshow(pilt)

Pildi info

Loeme põhilised andmed pildi kohta: pildi laius, kõrgus ja kihtide või mõõtmete arv. Kui on RGB pilt siis on 3 (kõrgus, laius, sügavus: RGB) mõõdet. Aga kui halltoonides pilt siis 2 (kõrgus, laius).

print('Pildi kuju (Shape): {}'.format(pilt.shape)) 
print('Pildi kõrgus: {}px'.format(pilt.shape[0])) 
print('Pildi laius: {}px'.format(pilt.shape[1]))
print('Mõõtmete (dimensioonide) arv: {}'.format(pilt.ndim))

Kui on halltoonides (Grayscale) pilt siis saame sellised andmed:

pilt_hall = imageio.imread(kataloog + 'image_hall.jpg')
print('Pildi kuju (Shape): {}'.format(pilt_hall.shape)) 
print('Pildi kõrgus: {}px'.format(pilt_hall.shape[0])) 
print('Pildi laius: {}px'.format(pilt_hall.shape[1]))
print('Mõõtmete arv: {}'.format(pilt_hall.ndim))

Järgmine pilt sisaldab ka läbipaistvuse (Alpha) kanalit.

pilt_alpha = imageio.imread(kataloog + 'image_alpha.png')
print('Pildi kuju (Shape): {}'.format(pilt_alpha.shape)) 
print('Pildi kõrgus: {}px'.format(pilt_alpha.shape[0])) 
print('Pildi laius: {}px'.format(pilt_alpha.shape[1])) 
print('Mõõtmete arv: {}'.format(pilt_alpha.ndim))

Pildi suuruse arvutamine:

print('Pildi suurus on {}'.format(pilt.size))

Suurima ja vähima RGB väärtuse leidmine:

print('Suurim RGB väärtus sellel pildil: {}'.format(pilt.max()))
print('Väikseim RGB väärtus sellel pildil: {}'.format(pilt.min()))

Ühe konkreetse piksli väärtuste vaatamine: piksel real (y-telg) 100 ja tulbas (x-telg) 50:

y = 100
x = 50
print('R kanal: {}'.format(pilt[ y, x, 0]))
print('G kanal: {}'.format(pilt[ y, x, 1]))
print('B kanal: {}'.format(pilt[ y, x, 2]))

Kanalite vaatamine

Vaatame igat pildi RGB kanalit eraldi:’

plt.title('R kanal') 
plt.ylabel('Kõrgus {}'.format(pilt.shape[0])) 
plt.xlabel('Laius {}'.format(pilt.shape[1])) 
plt.imshow(pilt[ : , : , 0])
plt.show()
R kanal
R kanal
plt.title('G kanal') 
plt.ylabel('Kõrgus {}'.format(pilt.shape[0])) 
plt.xlabel('Laius {}'.format(pilt.shape[1])) 
plt.imshow(pilt[ : , : , 1])
plt.show()
plt.title('B kanal') 
plt.ylabel('Kõrgus {}'.format(pilt.shape[0])) 
plt.xlabel('Laius {}'.format(pilt.shape[1])) 
plt.imshow(pilt[ : , : , 2])
plt.show()

Pikslite manipuleerimine

Muudame pildi mingis osas kanalite intensiivsust: Punasel (R) kanalil read 50 kuni 250. Muudame intensiivsuse maksimaalseks (255).

temp_1 = pilt.copy() # teeme pildist koopia
temp_1[50:250 , : , 0] = 255 # full intensity to those pixel's R channel 
plt.figure( figsize = (5,5)) 
plt.imshow(temp_1) 
plt.show()

Rohelisel (G) kanalil, read 250 kuni 450.

temp_1[250:450 , : , 1] = 255 # full intensity to those pixel's G channel 
plt.figure( figsize = (5,5)) 
plt.imshow(temp_1) 
plt.show()

Sinisel kanalil, read 450 kuni 600.

temp_1[450:600 , : , 2] = 255 # full intensity to those pixel's B channel 
plt.figure( figsize = (5,5)) 
plt.imshow(temp_1) 
plt.show()

RGB kanalid erinevatele piltidele

Impordime uue teegi numpy.

import numpy as np

fig, ax = plt.subplots(nrows = 1, ncols=3, figsize=(15,5))  
for c, ax in zip(range(3), ax):     
     # create zero matrix        
     split_img = np.zeros(pilt.shape, dtype="uint8") 
     # 'dtype' by default: 'numpy.float64'  # assing each channel      
     split_img[ :, :, c] = pilt[ :, :, c] # display each channel     
     ax.imshow(split_img)

Halltoonid

Halltoonides pilt on 2 mõõtmeline massiiv (Ing. array). Et viia pilti halltoonidesse peame kuidagi kokku liitma praegu kolmel erineval kihil oleva pildi info. Üks põhjus miks kasutatakse andmetöötluses halltoonides pilte on, et vähendad töödeldavate andmete hulka (1/3 võrreldes täis RGB pildiga). Üks võimalik valem on selleks:

Y′=0.299R+0.587G+0.114B

pilt = imageio.imread(kataloog +'image.jpg') 
gray = lambda rgb : np.dot(rgb[... , :3] , [0.299 , 0.587, 0.114])
gray = gray(pilt)
#plt.figure( figsize = (5,5))  
plt.imshow(gray, cmap = plt.get_cmap(name = 'gray')) 
plt.show()

Lingid

2 Comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.