Predavanje 4: Glave 10 i 11

FlipView[{Text[Style[" Branko Urošević, imqfbrankourosevic@gmail.com ",20,"Text",Italic]],Text[Style[" Faculty of Economics, University of Belgrade, NBS and CESIfo Munich",20,"Text", Italic]]}]

10. Slike (Images)

Mnoge funkcije u Wolfram Language rade sa slikama. Ukoliko iskopirate neku digitalnu sliku i prebacite je u WL možete da je dalje obrađujete (nešto kao Photoshop na steroidima). Ovde sam pozvao Wolfram Alpha da mi prikaže sliku orhideje.

Pravljenje negativa slike- ColorNegate

Na slike možete da primenite funkcije kao i na svaki drugi objekat. Evo kako radi  ColorNegate koja daje negativ slike koju imamo pred sobom (na taj način vaš profa postaje negativac!):

ColorNegate[]

Da li su grafici slike? Da bismo to proverili, konstruišimo prvo crveni krug

Graphics[Style[Disk[],Red]]

Sada nađimo njegov negative:

ColorNegate[Graphics[Style[Disk[],Red]]]

Razmazivanje slike - Blur

Blur razmazuje sliku:

Blur[]

Razmazivanje može da se obavi u gradaciji (što se kontroliše preko n).

Table[Blur[,n],{n,0,20,5}]

Probajmo to isto sa krugom:

Table[Blur[Graphics[Style[Disk[],Red]],n],{n,0,20,5}]

Kolaž slika - ImageCollage

ImageCollage pravi kolaž od neke liste slika koja mu je na raspolaganju. Ovde uzmemo prethodnu listu razmazanih slika pa od nje napravimo kolaž.

ImageCollage[Table[Blur[,n],{n,0,20,2}]]

Uradimo to isto sa crvenim krugom

ImageCollage[Table[Blur[Graphics[Style[Disk[],Red]],n],{n,0,20,4}]]

Određivanje glavnih boja: DominantColors

Puno drugih stvari možemo da uradimo sa slikama. DominantColors određuje u ovom slučaju 5 dominantnih boja sa slici:

DominantColors[,5]

Zanimljivo je da u crvenom krugu nema samo crvene boje!

DominantColors[Graphics[Style[Disk[],Red]],5]

Pravljenje crno bele slike - Binarize

Binarize pravi od slike crno-belu:

Binarize[]

Manipulate[Binarize[,n],{n,0,1}]

Pogledajmo kako to radi sa plavom loptom

Manipulate[Binarize[Graphics3D[Style[Sphere[],Blue]],n],{n,0.1,0.7}]

Detekcija granica objekta na slici - EdgeDetect

Još jedan način da analiziramo sliku jeste da detektujemo granice objekata, to jest da nađemo mesta gde se boja značajno menja. Rezultat je nešto što liči na skicu.

EdgeDetect[]

Graphics3D[Style[Sphere[],Blue]]

EdgeDetect[Graphics3D[Style[Sphere[],Blue]]]

Sabiranje slika - ImageAdd

Još jedna vrlo interesatna funkcija je ImageAdd. Recimo, ukoliko želimo da dodamo svetlo svim kanalima na slici istovremeno, možemo to ovako uraditi

ImageAdd[,0.15]

Možemo napraviti Manipulate koji to pojašnjava

Manipulate[ImageAdd[,svetlo],{svetlo,0.02,0.5}]

Drugi način korišćenja te funkcije jeste da spojimo dve slike u jednu:

ImageAdd[Graphics[Style[Disk[],Pink]],]

Operacija nije komutativna, to jest dobijamo potpuno drugu sliku ako promenimo mestima dva grafika.

ImageAdd[,Graphics[Style[Disk[],Pink]]]

Da li formatiranje slova ili brojeva jeste slika?

Primetimo da ovo nije slika:

Style[10,Red]

EdgeDetect[Style[10,Red,40]]

Međutim, ovo jeste slika:

Graphics[Text[Style[10,Red,40]]]

EdgeDetect[Graphics[Text[Style[10,Red,40]]]]

Q and A

CurrentImage daje tamnu sliku. Šta da radim? 
Probaj ponovo. Kad je kamera prvi put uključena nije možda baš automatski podesila svetlo. 

Šta znače nivoi u funkciji Blur?
To je rang piksela koji su zamazani zajedno.

Kako Binarize odlučuje šta je crno i šta je belo?
Ako mu ne kažete koja je granica, ova funkcija to radi na osnovu analize raspodele boja na slici. 

To što slike mogu diretno da se pojave u WL kodu je konsekvenca toga da je WL simbolički jezik. 
Jednostavan način da dobijemo slike npr krokodila jeste da uradimo ovako nešto:

WikipediaData["crocodiles", "ImageList"]

11. Stringovi i tekstovi (Strings and texts)

Pojam stringa u WL

Wolfram Language dozvoljama da se izračunavaju stvari koje sadrže tekst. String je bilo šta što otkucate ukoliko stavite to u znake navoda (“).

"This is a string"

Head["This is a string"]

String funkcije prenesene iz funkcija za liste

String output izgleda skoro isto kao string input osim što se ne vide znaci navoda. Mnoge funkcije rade sa stringovima, a mnoge od njih su direktan analog funkcija koje rade na lista, samo im se doda, tipično, prefiks String. Na primer, StringLength izračunava dužinu stringa, odnosno broj karaktera u njemu:

StringLength["hello"]

StringLength["This is"]

Vidimo da StringLength prazan prostor računa kao karakter.

StringReverse piše string u obratnom poretku:

StringReverse["hello"]

StringReverse["This is"]

Posebne string funkcije

ToUpperCase čini da svi karakteri postanu velika slova:

ToUpperCase["I'm coding in the Wolfram Language!"]

ToLowerCase čini da svi karakteri postanu mala slova

ToLowerCase["I'm coding in the Wolfram Language!"]

Nekada je korisno da se brojevi ili simboli pretvore u stringove. Na primer

Head[123]

ToString[123]

Head[ToString[123]]

Kako izdvojiti karaktere

Nije teško pogoditi kako da izdvojite prvih 10 karaktera nekog stringa:

StringTake["this is about strings",10]

Zaista, dobijeni string ima upravo 10 karaktera

StringLength[StringTake["this is about strings",10]]

Kako spojiti dva stringa

StringJoin spaja stringove (ne zaboravite prazan prostor koji razdvaja reči jedne od drugih):

StringJoin["Hello"," ","there!"," How are you?"]

Često se koristi i sledeća skraćena verzija StringJoin, a naime <>

"Hello"<>" "<>"there!"<>" How are you?"

Od brojeva ka stringovima: ToString

Evo primera kako možemo da spojimo dva stringa koji se sastoje od brojeva. Naime, razmotrimo

ToString[123]<>ToString[586]

Proverimo da je to zaista string:

Head[ToString[123]<>ToString[586]]

ToString[123]<>((ToString[586])^2)

Dakle, string se ne može kvadrirati i slično

Od stringa ka izrazu odnosno broju: ToExpression

Primetimo da iz ovog stringa možemo ponovo dobiti broj koristeći ToExpression

ToExpression[ToString[123]<>ToString[586]]

Da je ovo broj možemo da potrdimo ovako

((ToExpression[ToString[123]<>ToString[586]])^2)

Operacije na listi stringova

Razmotrimo sada listu stringova:

{"apple","banana","strawberry"}

StringLength[{"apple","banana","strawberry"}]

Ovako izdvajamo prva dva karaktera u svakom od 3 stringa:

StringTake[{"apple","banana","strawberry"},2]

Razbijanje stringa na pojedinačne karaktere

Nekada je korisno razbiti string u listu karaktera iz koje se sastoji. Svaki od karaktera je string dužine 1.

Characters["a string is made of characters"]

Kada ste razbili string na listu karaktera, na tu listu možete da primenite funkcije za List (pre nego što razbijete String na pojedinačne karakter, string je jedinstven objekat, Atom, a ne lista. Na primer, ako želimo da sortiramo ovaj string:

Sortiranje karaktera u stringu

Sort[Characters["a string of characters"]]

Nevidljivi karakteri na početku liste su space (prazan prostor) karakteri. Ukoliko želite da vidite string u formi u kakvoj ste je ukucali, sa sve znacima navoda, možete da koristite InputForm:

InputForm[Sort[Characters["a string of characters"]]]

Funkcija na testu: TextWords, TextSentences

Funkcije kao što su StringJoin i Characters rade sa svim stringovima; nema veze da li tekst od koga se sastoji neki string ima smisla ili ne. Ima drugih funkcija kao što je TextWords, koje specifično rade sa smislenim tekstom napisanim, na primer, na engleskom. TextWords uzima string i razbija ga na listu reči:

TextWords["This is a sentence. Sentences are made of words."]

TextSentences razbija tekst na listu rečenica:

TextSentences["This is a sentence. Sentences are made of words."]

Unošenje teksta iz Wikipedia

Ima puno načina da se unese tekst u Wolfram Language. Jedan primer jeste WikipediaData funkcija. Ona uzima trenutni tekst iz Wikipedia članka o nečemu. Ovako uzimamo prvih 100 karaktera Wikipedia teksta o “computers”:

StringTake[WikipediaData["computers"],100]

WordCloud

Jednostavan način da se vidi od čega se sastoji deo teksta jeste WordCloud. Da bismo izbegli nezanimljive reči kao što su  “the” i “and” (koji se na engleskom zovu stopwords), koristimo funkciju DeleteStopwords. Evo kako možemo da napravimo WordCloud reči koji ulaze u Wikipedia članak o “computers”:

WordCloud[DeleteStopwords[WikipediaData["computers"]]]

Nije iznenađenje da “computer” i “computers” jesu veoma česte reči koje se koriste u tom članku.

Engleska azbuka

Alphabet daje englesku azbuku:

Alphabet[]

LetterNumber daje redni broj slova u azbuci:

LetterNumber[{"a","b","x","y","z"}]

Malo numerologije!

Hajde da se malo bavimo numerologijom. Recimo, kako da napišemo broj koji odgovara reče “Numerology”. Da bismo to uradili, razbijmo reč na karaktere, nađimo LetterNumber za svaki, i tako dobijene cifre spojimo u broj.

LetterNumber[Characters["Numerology"]]

Ako hoćemo da spojimo ove brojeve u jedan broj, jedan od načina jeste da napravimo od njih ponovo stringove, pa da onda spojimo stringove i pretvorimo dobijeni spojeni string u broj.

Table[ToString[k],{k,LetterNumber[Characters["Numerology"]]}]

StringJoin[Table[ToString[k],{k,LetterNumber[Characters["Numerology"]]}]]

Ovo je string

InputForm[StringJoin[Table[ToString[k],{k,LetterNumber[Characters["Numerology"]]}]]]

Ovako dobijamo broj:

ToExpression[StringJoin[Table[ToString[k],{k,LetterNumber[Characters["Numerology"]]}]]]

Na ovaj način, reč na engleskom jeziku pretvara se u broj.To može da se koristi, recimo, za kriptovanje poruka (o kriptovanju poruka na druge načine videćemo kasnije)

Druge azbuke

Alphabet zna i neke ne-engleske azbuke takođe (u verziji 11 je i Serbian jedna od mogućnosti):

Alphabet["Russian"]

Alphabet["Croatian"]

Recimo, da li ovo radi?

LetterNumber["č","Croatian"]

LetterNumber["dž","Croatian"]

Znači, uz neke izmene, sve što smo uradili sa engleskom reči “numerology” možemo sa bilo kom reči napisanom na našoj latinici (srećom te Wolfram nije izabrao crnogorsku azbuku....).

Ukoliko želite da string pretvorite u sliku: Rasterize

Ukoliko to želite, tekst se može pretvoriti u sliku, a slike se mogu manipulisati kao i svake druge. Funkcija Rasterize pravi bitmapu ili raster, nečega. Generišimo prvo sliku dela teksta koristeći Rasterize funkcije, a onda potražimo njene ivice preko EdgeDetect:

Rasterize[Style["ABC",100,Red]]

Posle toga možete da koristiti rasterizovanu sliku stringa kako god želite.

EdgeDetect[]

Napravite listu cifara broja (2^1000) sa slučajnim bojama i veličinom koristeći stringove

Pođimo od broja

(2^1000)

Možemo ga pretvoriti u string i razbiti na karaktere

Characters[ToString[(2^1000)]]

Table[Style[cifre,RandomColor[],RandomInteger[{10,30}]],{cifre,Characters[ToString[(2^1000)]]}]

Svaki element tabele ovde je string. Možemo ga pretvoriti u grafik:

Table[Rasterize[Style[cifre,RandomColor[],RandomInteger[{10,30}]]],{cifre,Characters[ToString[(2^1000)]]}]

A sada od tabele grafika možemo napraviti kolaž:

ImageCollage[Table[Rasterize[Style[cifre,RandomColor[],RandomInteger[{10,30}]]],{cifre,Characters[ToString[(2^1000)]]}]]

Rimski brojevi

Rimski brojevi su u WL stringovi. Dobijaju se komandom RomanNumeral[broj]

RomanNumeral[21]

Head[RomanNumeral[21]]

Između ostalog, ako probamo da uradimo sledeće

RomanNumeral[21]+RomanNumeral[27]

Drugim rečima neće se izračunati suma pošto su to stringovi

Od rimskih brojeva do običnih arapskih brojeva

A evo kako se rimski brojevi konvertuju u obične, arapske brojeve

FromDigits["XXI","Roman"]

Na primer, ako rimske brojeva prvo pretvorimo u arapske, pa ih saberemo, to će onda raditi

FromDigits[RomanNumeral[21],"Roman"]+FromDigits[RomanNumeral[24],"Roman"]

Naravno tako dobijeni broj može opet da se pretvori u rimski

RomanNumeral[FromDigits[RomanNumeral[21],"Roman"]+FromDigits[RomanNumeral[24],"Roman"]]

Napravite tabelu rimskih brojeva od 50 do 100

To je jednostavno. Naime, tabela brojeva od 50 do 100, koristeći Table, bi bila

Table[n,{n,50,100}]

Za rimske brojeva bila bi

Table[RomanNumeral[n],{n,50,100}]

Nađite maksimalan broj karaktera u ovoj listi brojeva. Broj karaktera u stringu dobija se preko StringLength. Na primer

StringLength["LXXX"]

StringLength radi pokomponentno

StringLength[Table[RomanNumeral[n],{n,50,100}]]

Stoga je maximum

Max[StringLength[Table[RomanNumeral[n],{n,50,100}]]]

Q and A

U čemu je razlika između “x” i x?
“x” je string, x je simbol u WL, kao Plus ili Max. Mi ćemo pričati kasnije puno više o simbolima.

Kako da unesem karakter koji ne postoje na tastaturi?
Mnogi karakteri postoje u Palleti Special Characters. Ima i drugih načina.

Kako da unesem (“)  unutar stringa?
Koristi \” (a ako želite da stavite  \” bukvalno u string, koristite \\ \”). (Ako želite da imate unutar stringa \\ \” onda bi morali da uradite: \\ \\ \\ \”.)

Šta raditi sa azbukama koje nisu engleski? Da li su one numerisane?
LetterNumber[“α”, “Greek”] daje numeraciju tog slova u grčkoj azbuci. Svi karakteri imaju svoj karakter code. Da bismo ga saznali koristimo ToCharacterCode.

Kako su boje u WordCloud određene?
Po defoltu postoji određena paleta, ali možete da to menjate ako želite. 

Tehnički komentari

StringTake[“string”, -2] uzima 2 poslednja karaktera na kraju stringa. 

Svaki karakter, bilo da je “a”, “α” ili “狼” ima svoj Unicode character code, koji se dobija kada napravimo ToCharacterCode. Možete da idete obrnuto, od brojeva ka karakterima koristeći FromCharacterCode. O tome ćemo kasnije da pričamo.

Ako dobijete drugačiji rezultat koristeći WikipediaData, to je zato što se članak promenio.