Arvutiteaduse instituut
  1. Kursused
  2. 2025/26 sügis
  3. Programmeerimine (LTAT.03.001)
EN
Logi sisse

Programmeerimine 2025/26 sügis

  • Üldinfo
  • 1. Muutuja ja avaldis
  • 2. Tingimuslause
  • 3. Funktsioon
  • 4. Korduslause
  • 5. Sõned. Lihtsam failitöötlus
  • 6. Kontrolltöö 1
  • 7. Järjend
  • 8. Järjend 2
  • 9. Kahekordne tsükkel. Failitöötlus
  • 10. Andmestruktuurid
  • 11. Andmestruktuurid 2
  • 12. Kontrolltöö 2
  • 13. Objektorienteeritud programmeerimine
  • 14. Objektorienteeritud programmeerimine 2
  • 15. Rekursioon
  • 16. Kordamine. Projektide esitlused
  • Viiteid
  • Silmaringimaterjalid

Arhiveeritud esialgsed silmaringimaterjalid

  1. Standardteek ja moodulid
  2. Rakendusliidesed
  3. Regulaaravaldised
  4. Andmebaasid
  5. Veebirakenduste loomine
  6. Objektorienteeritud programmeerimine
  7. Graafiliste mängude loomine
  8. Keerulisemad Pythoni võimalused
  9. Võistlusprogrammeerimine
  10. Veebisisu parsimine
  11. Pilditöötlus
  12. Pythoni siseehitus
  13. Helitöötlus
  14. Kodeerimine ja krüpteerimine
  15. NumPy
  • Materjalid

Pilditöötlus

Siin peatükis saab tutvuda pilditöötlusega ning tööriistadega, mis Pythonis selle tarvis on. Selle jaoks antakse kõigepealt ülevaade värvimudelitest ning selgitatakse, millised on levinud pildivormingud ning mille poolest nad erinevad.

Ettevalmistus

Juhend eeldab, et oled tutvunud Pythoni järjenditega. Enne alustamist tuleks paigaldada PIL-nimeline teek käsuga pip install Pillow. Vajadusel loe läbi õpikus moodulite paigaldamise juhised.

Värvimudelid


Värvide hulk erinevates mudelites.
Allikas: Crazydude

Juba õige ammu märgati, et kõiki värve, mida inimese silm eristab, on võimalik kokku panna kolmest põhivärvist: sinine, punane ja kollane. Seda nimetatakse subtraktiivseks värvimudeliks, sest valge saamiseks peab värve mustast "lahutama" ja kõiki värve kokku pannes saab musta. Iga põhivärvi kogust võib numbriliselt väljendada skaalal 0-100, nii et näiteks halle toone kirjeldavad sellised segud, kus kõiki värve on võrdselt. Teoorias oleks keskmiselt hall toon segu (50, 50, 50) ja must oleks segu (100, 100, 100), aga kuna saadaolevate värvide kvaliteet varieerub, võib praktikas värve segades tihti saada hoopis tumepruuni.

CMYK

Tänapäeva printerid kasutavad samasugust tuttavat värvimudelit, kuigi on leitud, et täpsema tulemuse jaoks on parem kasutada põhivärvidena tsüaansinist, magentapunast ja kollast. Selle mudeli nimi on CMYK (Cyan-Magenta-Yellow-Key), kus viimase värvina on lisatud key ehk "võtmevärv" must. Viimane lisati juurde, sest avastati, et kui üritada paberile printides musta saamiseks teisi tinte maksimaalses koguses segada, siis on tulemuseks natuke vettinud välimusega kole paber ja üsna mitterahuldav värvitoon.

RGB ja RGBA

Ekraanid seevastu kasutavad RGB (Red-Green-Blue) värvimudelit, mis on aditiivne mudel ehk valge saamiseks tuleb kõik kolm erinevat värvi valgust liita (must on pimedus!). RGB-mudelis on põhivärvide intensiivsused tavaliselt skaalal 0-255, nii et ühe piksli värvi salvestamiseks piisab täpselt kolmest baidist (255 on suurim arv, mis ühte baiti mahub). Lühema kirjapildi huvides kirjutatakse RGB värve tihti ka kuueteistkümnendkoodidena, kus prefiks on #:

VärvRGBVastav heksakood
Must000 #000000
Valge255255255 #ffffff
Punane25500 #ff0000
Roheline02550 #00ff00
Sinine00255 #0000ff
Lilla1270127 #7f007f
Pruun1654242 #a52a2a

RGBA mudelis on lisatud neljandaks alfakanal, mis määrab kui läbipaistev piksel on (0 = täiesti läbipaistev). See lihtsustab näiteks üleminekute ja varjude loomist veebikujunduses.

LAB

LAB mudelis on L (lightness) heleduse telg, A (alfa) on sinine-kollane telg ja B (beeta) on roheline-punane telg. See mudel kirjeldab kõige paremini seda, kuidas inimese silm värve näeb ja seega saab sellega kõige rohkem erinevaid silmale nähtavaid värve väljendada. Samuti annavad mitmed teisendused seda mudelit kasutades silmale loomulikuma tulemuse, näiteks pildi värvide pööramine:


Allikas: Python Image Processing Cookbook

Mustvalge või monokroomne

Mustvalges või ühevärvilises värvimudelis on ainult heleduse telg - üks täisarv määrab, kui hele või tume piksel on. Mustvalge värvimudel võib olla ka ainult kahevärviline, nii et ühe bitiga saab määrata, kas piksel on must või valge.

Teised mudelid

On veel mitmeid teisi mudeleid. Pilditöötlusprogrammides võib kokku puutuda hue (värvitoon), saturation (küllastus) ja brightness (heledus) väärtustega. Need parameetrid moodustavad HSB värvimudeli, kus H ehk hue on olemuselt värviratas - selle võimalikud väärtused on skaalal 0-360. Küllastus ja heledus on kumbki skaalal 0-100.

Vaata ka https://docs.python.org/3/library/colorsys.html Järgmiselt lingilt leiab kõik värvimudelid (või režiimid), mis teegis PIL kasutatavad on: https://pillow.readthedocs.io/en/stable/handbook/concepts.html#modes

Harmooniline disain

Raamatute, ajakirjade, riiete, kasutajaliideste ja arvutimängude disainimisel on mõistlik arvestada sellega, kuidas värvid ja nende kombinatsioonid inimestele mõjuvad. Sellega tegeleb värviteooria, kuigi süvitsi me seda siin peatükis uurima ei hakka. Kasulik on teada, et hea värvikompositsioon on harmooniline ja harmooniaid ehk värvikõlasid on erinevaid. Näiteks moodustavad värvikõla kõrvuti asetsevad värvid, ühe värvitooni variatsioonid, aga ka vastandvärvid.

Harmooniad valitakse tavaliselt värviratta abil, mis on sisuliselt ringikujuliselt joonistatud värvispekter. Kõigepealt paigutatakse ringile põhivärvid, seejärel iga kahe põhivärvi vahele nende segu. Nii on lihtne leida vastandvärve - need on alati 180° kaugusel ehk ringi vastaspoolel! Igas värvimudelis ei teki samad harmooniad, sest põhivärvid ja seega ka värviringid on erinevad. Erinevaid värvikõlasid saad valida siin: https://www.sessions.edu/color-calculator/.

Pildifailid ja -vormingud

Pildiformaadid on erineva otstarbega, mõnda kasutatakse veebis graafika kuvamiseks, teised sobivad paremini näiteks printimiseks. Mõned on loodud väiksema faili suuruse saavutamiseks faili kvaliteedi või värvivaliku arvelt.

Joint Photographic Experts Group (.jpeg .jpg)

Paljud digitaalkaamerad salvestavad pilte JPEG-vormingus. Pildid pakitakse kadudega, et failisuurust väiksemana hoida, mis tähendab, et iga kord, kui pilti pärast muutmist salvestatakse, kaob mingi hulk infot. Tihti ei paista see pilti vaadates silmagi, aga korduvalt JPEG-faile muutes ja salvestades võib detaile kaduma minna.

Portable Network Graphics (.png)

.png on kõige populaarsem vorming, millega veebis graafikat kuvatakse, sest see talletab infot kadudeta ning sellega on võimalik salvestada ka läbipaistvusega piksleid. PNG-failid salvestavad infot RGBA värvimudeli abil ja ühe piksli kohta info salvestamiseks kasutatakse maksimaalselt 64 bitti (värvisügavus = 4*16 bitti). Ühel pildil võib seega kasutada kuni 2**64 erinevat värvitooni (erinevad läbipaistvusastmed kaasa arvatud).

Graphics Interchange Format (.gif)

GIF-vorming on PNG-vormingu eelkäija ja suudab salvestada pilte kuni 256 vabalt valitud värviga, kusjuures iga piksel võib olla ka täiesti läbipaistev. Lisaks toimib GIF-fail piltide jadana - ühte faili saab salvestada mitu pilti, nii et tulemuseks on animeeritud pilt. Pikemate videote salvestamiseks seda siiski ei kasutata, sest paljude kaadritega GIF-fail muutub ruttu väga mahukaks ning selle kuvamine võtab kaua aega. Kuna PNG animeeritud variandid pole populaarseks saanud, siis kasutataksegi animeeritud pildikeste jaoks GIF-vormingut.

Bitmap (.bmp .dib)

BMP-faile ei pakita, seega kipuvad nad päris suured olema. Samas on programmidel neid lihtne lugeda, sest faili sisu ei pea kuidagi lahti pakkima (teisendama). Üks pilt võib kulutada kuni 32-bitti piksli kohta ja peamiselt kasutab seda vormingut Windowsi operatsioonisüsteem.

Scalable Vector Graphics (.svg)

Eelnevalt vaatasime rastergraafika formaate, kus igal pikslil on mingi värviväärtus. Vektorgraafika on pigem objektorienteeritud - pilt koosneb võrrandite abil kirjeldatud kujunditest ja joonistamisinstruktsioonidest. SVG-fail on tegelikult XML-struktuuriga fail, mis võib sisalda ka CSS-elemente (loe viimaste kohta lähemalt veebisisu parsimise peatükist) ning seda pakitakse ilma detaile kaotamata - pildi detailsust saab reguleerida muutmise ajal. Eeliseks on see, et pilte saab skaleerida ilma kvaliteeti kaotamata, samas on realistlikke kujutisi ja fotosid keeruline täpselt salvestada, kuna nende kirjeldamiseks on vaja väga palju objekte. Vorming sobib hästi kaartide ja logode tegemiseks.

Enesekontrolliküsimused

Pilditöötlusteek PIL

Pythonis on rastergraafika piltidega ümber käimiseks võimalik kasutada teeki PIL (Pillow). See koosneb mitmest moodulist, mille täieliku nimekirja leiab dokumentatsioonist: https://pillow.readthedocs.io/en/stable/reference/. Vaatame mõningaid:

  • Image - Põhimoodul. Sisaldab Image klassi ja muud vajalikku piltide avamiseks, salvestamiseks, töötlemiseks.
  • ImageChops - Matemaatilised või loogilised operatsioonid piltidega (pikslimaatriksitega).
  • ImageColor - Funktsioonid värvikoodide teisendamiseks mõnda teise värvisüsteemi.
  • ImageDraw - Pildile joonistamise ja kirjutamise funktsioonid.
  • ImageEnhance - Klassid, mille abil saab pildi värvitasakaalu, kontrasti, heledust ja teravust reguleerida.
  • ImageFilter - Erinevad pilditeisendused ja nende koostamise vahendid.
  • ImageOps - Sisaldab rohkem kõrgetasemelisi pilditeisendusfunktsioone.
  • ImageSequence - Animeeritud piltide itereerimiseks.
  • ImageTk - Pildiobjektide teisendamiseks mooduli Tkinter jaoks sobivasse vormingusse.

Tasub teada, et kui on lisaks vaja videotöötluse, masinnägemise või tehisintellekti vahendeid, on mõistlikum kasutada PIL asemel openCV teeki.

Failivormingu muutmine

PIL suudab avada kõiki populaarsetes formaatides pilte ning salvestada neid ümber teise formaati. Kuigi PDF-faile selle abil sisse lugeda ei saa, võimaldab PIL salvestada pilte PDF-kujul, mis sobib hästi näiteks printimiseks. Järgmine koodilõik demonstreerib, kuidas avada .png laiendiga fail ja salvestada see .jpg vormingusse.

Pildifail: python-logo.png

from PIL import Image

img = Image.open("python-logo.png")
img = img.convert("RGB") # Võib juhtuda, et mõnda pilti peab teisendama
img.save("python-logo.jpg")

img.convert() on siin vajalik, sest sisendfail on salvestatud RGBA-režiimis, aga PIL ei luba JPEG-faile selles režiimis salvestada. Kuna salvestame JPEG-vormingusse, siis pakitakse pilt kadudega, aga JPEG-piltide puhul saab parameetriga quality määrata, kui palju infot kaduma läheb. Näiteks img.save("python-logo.jpg", quality=100) jätab kõik detailid alles, aga siis tuleb fail ka palju suurem kui algne PNG-kujutis.

Piltide kuvamine

Kõige lihtsam on pilte kuvada meetodiga show, mis peaks avama pildi operatsioonisüsteemi vaikefotovaaturis.

Kui Pythoni mooduli Tkinter abil teha kasutajaliides, siis saab koos PIL mooduli ImageTk abiga seal pilte kuvada:

from tkinter import *
from PIL import Image, ImageTk

root = Tk()
canvas = Canvas(root)

img = Image.open("python-logo.png")
imgTk = ImageTk.PhotoImage(img)
canvas.create_image(100,100,image=imgTk)

canvas.grid()
root.mainloop()

Lihtsamad teisendused

Järgnev kood teeb Pythoni logo erinevatest teisendustest järjendi ja kuvab iga teisenduse:

from PIL import ImageOps

teisendused = [
    img.rotate(45, expand=True), # 45-kraadine pööre
    img.transpose(Image.Transpose.FLIP_TOP_BOTTOM), # Vertikaalne peegeldus
    img.resize( (img.width//2, img.height//2) ), # Kahekordne vähendus
    img.crop( (50, 50, img.width-50, img.height-50) ), # Väljalõige keskelt
    ImageOps.grayscale(img), # Mustvalges värviskaalas
    ImageOps.invert(img), # Vastandvärvides
    ImageOps.expand(img, 5, "#00ff00") # Rohelise raamiga
]

for t in teisendused:
    t.show()

Üle pikslite itereerimine

Vahel on kasulik teisenduste kombineerimise asemel lihtsalt üle pildi pikslite itereerida ja ükshaaval muudatusi teha. Näiteks saab arvutada iga piksli kauguse pildi keskpunktist ja jätta alles ainult ringikujuline osa pildist:

centerX, centerY = img.width//2, img.height//2

for x in range(img.width):
    for y in range(img.height):
        # Muuda läbipaistvaks, kui piksel on kaugemal kui 55px
        if (x-centerX)**2 + (y-centerY)**2 > 55**2:
            img.putpixel((x,y), (0,0,0,0))

img.show()

Filtrid

Moodulist ImageFilter leiab mitmeid filtreid, mida piltidele rakendada. Need on klasside kujul ning kasutada saab neid nii:

from PIL import ImageFilter

img.filter(ImageFilter.CONTOUR).show()
img.filter(ImageFilter.EMBOSS).show()
img.filter(ImageFilter.BoxBlur(3)).show()
img.filter(ImageFilter.MedianFilter(13)).show()
img.filter(ImageFilter.MinFilter(7)).show()
CONTOUREMBOSSBoxBlur(3)MedianFilter(13)MinFilter(7)
Kuidas filtrid töötavad?

Eelnevalt kirjeldatud pildifiltreid on võimalik ka ise kokku panna matemaatilistest teisendustest, mida nimetatakse konvolutsioonideks. Tuleb lihtsalt teada, millist maatriksit pildi igale pikslile rakendada, et soovitud tulemus saada. Seejärel tehakse vaadeldavast pikslist ning seda ümbritsevatest pikslitest maatriks. Pikslimaatriksi ja valitud teisendusmaatriksi (kernel) vahel tehakse nüüd maatriksite korrutamisele sarnanev tehe. Näiteks järgneva teisendusmaatriksi abil saab piksli 'e' väärtuseks selle alloleva piksli kolmekordne + ülalasuva piksli kahekordne väärtus.

{$ $}{$ \begin{bmatrix} a & b & c \\
d & \boldsymbol{\color{green} e} & f \\
g & h & i \end{bmatrix} \begin{bmatrix} 0 & 3 & 0 \\
0 & 0 & 0 \\
0 & 2 & 0 \end{bmatrix} = (i \cdot 0)+(h \cdot 3)+(g \cdot 0)+(f \cdot 0)+(e \cdot 0)+(d \cdot 0)+(c \cdot 0)+(b \cdot 2)+(a \cdot 0) = \color{green} {3 \cdot h + 2 \cdot b} $}

Praktikas ei pea neid detaile ilmtingimata teadma, sest klass ImageFilter.Kernel loob ise vajaliku teisenduse etteantud kerneli ja mõne lisaparameetri põhjal:

# Pildi teravustamise kernel:
m_sharpen = [
    0, -.5, 0,
    -.5, 3, -.5,
    0, -.5, 0
]
kernel = ImageFilter.Kernel((3,3), m_sharpen, 1)

sharpened = img.filter(kernel)
sharpened.show()

Kuma lisamine

Hetkel pole teegis PIL funktsiooni, millega pildile kuma või varju lisada. Vaatame, kuidas seda siiski teha saab. Tahame näiteks Pythoni logo ümber kuma lisada. Selleks teeme pildist koopia, udustame selle ja kleebime algse logo uduse pildi peale.

Udustamiseks kasutame Gaussi udustamise meetodit. Värvilise kuma asemel varju saamiseks võib neljanda rea välja kommenteerida. Et läbipaistev kuma siin paremini nähtav oleks, kleebitakse ta valge tausta peale. Kleepimisel peaks täpsustama maski, et kogu pildiala üle ei kirjutataks.

from PIL import Image, ImageEnhance, ImageFilter

img = Image.open("python-logo.png")
img_blurred = img.copy()
img_blurred = img_blurred.filter(ImageFilter.GaussianBlur(radius=2))
img_blurred = ImageEnhance.Color(img_blurred).enhance(25) # Teeb varju värvi intensiivsemaks

result = Image.new("RGB", (img.width, img.height), (255, 255, 255)) # Valge taust
result.paste(img_blurred, mask=img_blurred)
result.paste(img, mask=img)
result.show()
+ =

Seotud kursused

Käsitletud teemadega on põhjalikumalt võimalik tutvuda kursustel "MTAT.03.015 Arvutigraafika" ja "MTAT.03.132 Multimeedia". Pildituvastust, muid masinõppe meetodeid ja teeki openCV tutvustatakse ka aines "LTAT.01.003 Tehisintellekt".

Enesekontrolliküsimused

Ülesanded

1. Kirjuta funktsioon, mis võtab sisendiks kausta nime ja värvisüsteemi, millesse PIL salvestada lubab, ning salvestab kõik pildid kaustas ümber sellesse süsteemi. Kui mõnda faili ei õnnestu teisendada, tuleks see vahele fail vahele jätta ja kasutajale teada anda.

2. Koosta programm, mis palub kasutajalt sisendiks pilti ja kuvab siis Tkinteri aknas kaheksa varianti sellest pildist, nii et igaühele on rakendatud mingit teisendust või teisenduste kombinatsiooni. Programm võiks ka lubada ühe teisendatud pildi soovitud nimega salvestada.

Vihje: Pildi avamiseks ja salvestamiseks saad kasutada mooduli tkinter.filedialog funktsioone askopenfile ja asksaveasfile.

  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused