• Nie Znaleziono Wyników

Obrázky (reprezentace, generování, úpravy)

N/A
N/A
Protected

Academic year: 2022

Share "Obrázky (reprezentace, generování, úpravy)"

Copied!
80
0
0

Pełen tekst

(1)

Obr´ azky (reprezentace, generov´ an´ı, ´ upravy)

IB111 Z´aklady programov´an´ı Radek Pel´anek

2018

1 / 74

(2)

Rozcviˇcka: ˇsifra

(3)

3 / 74

(4)

Uˇcel pˇredn´ ´ aˇsky

procviˇcen´ı z´akladn´ıch konstrukc´ı z jin´eho pohledu propojen´ı programov´an´ı a matematiky

t´ema

”reprezentace dat“

procviˇcen´ı

”ˇcten´ı k´odu“

podklad pro zaj´ımav´e cviˇcen´ı

(5)

Pozn´ amka k efektivitˇe, obr´ azk˚ um

uk´azky program˚u v pˇredn´aˇsce:

snaha o ˇcitelnost program˚u neefektivn´ı (pomal´e):

algoritmy

technick´a realizace (napˇr.

”putpixel“ vs

”load + pixel access object“)

n´ızk´a / rozliˇcn´a kvalita obr´azk˚u – ˇcistˇe pragmatick´e d˚uvody (nepˇr´ıliˇs velk´e PDF), ˇadn´a skryt´a pointa

5 / 74

(6)

Dalˇs´ı zdroje, n´ amˇety

obr´azky, zvuk, video:

kniha Introduction to Computing and Programming in Python, A Mutlimedia Approach, M. J. Guzdial, B.

Ericson.

http://coweb.cc.gatech.edu/mediaComp-teach

(7)

Reprezentace obr´ azk˚ u

Bitmapová grafika Vektorová grafika

(5,3) (5,27)

(5,15)

(25,3) (25,27)

7 / 74

(8)

Reprezentace barev

v´ıce barevn´ych model˚u (aditivn´ı, subtraktivn´ı)

budeme pouˇz´ıvat aditivn´ı model RGB – red, green, blue kaˇzd´a sloˇzka = hodnota 0-255 (8 bit˚u, 1 byte)

barva = trojice, napˇr. (15, 255, 100)

(9)

Knihovna Image

knihovna pro pr´aci s bitmapov´ymi obr´azky velmi bohat´a funkcionalita

pouˇzijeme jen z´akladn´ı operace:

new – vytvoˇren´ı obr´azku

open, convert – otevˇren´ı obr´azku, konverze na RGB m´od

getpixel – zjiˇstˇen´ı barvy bodu putpixel – zmˇena barvy bodu size – velikost obr´azku

show, save – zobrazen´ı, uloˇzen´ı

9 / 74

(10)

Knihovna Image – technick´e pozn´ amky

Python Imaging Library (PIL): jen pro Python 2 http://www.pythonware.com/products/pil/

implementace Pillow (i pro Python 3):

https://pypi.python.org/pypi/Pillow/2.1.0 from PIL import Image

(11)

N-tice

reprezentace souˇradnic a barev pomoc´ı n-tic (tuple) podobn´e jako seznamy, ale nemˇeniteln´e; z´apis pomoc´ı kulat´ych z´avorek

u obr´azk˚u typicky:

souˇradnice: (x, y) barva: (r, g, b)

11 / 74

(12)

Image demo

def demo():

im = Image.new("RGB", (20, 20), (255, 255, 255))

# model, velikost, barva pozadi im.putpixel((10, 10), (0, 0, 0))

im.putpixel((8, 7), (255, 0, 0)) im.putpixel((5, 13), (100, 255, 105)) im.show()

im.save("demo.png")

(13)

Geometrick´e ´ utvary

Napiˇste programy pro generov´an´ı n´asleduj´ıc´ıch ´utvar˚u:

čtverec trojúhelník kruh elipsa spirála

13 / 74

(14)

Kruh

def disc(a=150, r=50):

im = Image.new("RGB", (a, a), (255, 255, 255)) for x in range(a):

for y in range(a):

if XXX:

im.putpixel((x, y), (0, 0, 0)) im.show()

(15)

Kruh

def disc(a=150, r=50):

im = Image.new("RGB", (a, a), (255, 255, 255)) for x in range(a):

for y in range(a):

if (x-a/2)**2 + (y-a/2)**2 < r**2:

im.putpixel((x, y), (0, 0, 0)) im.show()

15 / 74

(16)

Barevn´ y kruh

(17)

Barevn´ y kruh

Barvu

”nam´ıch´ame“ podle vzd´alenosti od stˇredu kruhu:

d = math.sqrt((x-a/2)**2 + (y-a/2)**2) if d < r:

c = int(255*d/r)

im.putpixel((x, y), (c, 0, 255-c))

17 / 74

(18)

Barevn´e kruhy

(19)

Pˇrid´ an´ı n´ ahodn´eho kruhu do obr´ azku

def add_random_disc(im):

(width, height) = im.size

r = random.randint(8, min(width, height) // 6) sx = random.randint(r+1, width-r-1)

sy = random.randint(r+1, height-r-1) color = (random.randint(0, 255),

random.randint(0, 255), random.randint(0, 255)) for x in range(width):

for y in range(height):

if (x-sx)**2 + (y-sy)**2 < r**2:

im.putpixel((x, y), color)

19 / 74

(20)

N´ amˇet na procviˇcen´ı

(21)

Geometrick´e obrazce

21 / 74

(22)

Z´ akladn´ı princip

potˇrebujeme plynul´y pˇrechod mezi b´ılou a ˇcernou jakou matematickou funkci vyuˇzijeme?

sinus – hodnoty mezi -1 a 1, perioda 2π

potˇrebujeme – hodnoty mezi 0 a 255, perioda (napˇr.) 20

(23)

Z´ akladn´ı princip

potˇrebujeme plynul´y pˇrechod mezi b´ılou a ˇcernou jakou matematickou funkci vyuˇzijeme?

sinus – hodnoty mezi -1 a 1, perioda 2π

potˇrebujeme – hodnoty mezi 0 a 255, perioda (napˇr.) 20

22 / 74

(24)

Pruhy

def strips(size=150, count=5):

im = Image.new("RGB", (size, size)) for x in range(size):

for y in range(size):

z = math.sin(count * 2*math.pi * x/size) shade = int(255 * (z+1)/2)

im.putpixel((x,y), (shade, shade, shade)) im.show()

(25)

Vzory II

24 / 74

(26)

Mandelbrotova mnoˇzina

(27)

Mandelbrotova mnoˇzina

z1 = 0, c = x + yi je konstanta (komplexn´ı ˇc´ıslo) definujeme posloupnost

zn+1 = zn2+ c

c patˇr´ı do Mandelbrotovy mnoˇziny ⇔ tato posloupnost je omezen´a

26 / 74

(28)

Mandelbrotova mnoˇzina – detail

(29)

Mandelbrotova mnoˇzina – k´ od

_ = (

255, lambda

V ,B,c

:c and Y(V*V+B,B, c -1)if(abs(V)<6)else

( 2+c-4*abs(V)**-0.4)/i

) ;v, x=1500,1000;C=range(v*x );import struct;P=struct.pack;M,\

j =’<QIIHHHH’,open(’M.bmp’,’wb’).write for X in j(’BM’+P(M,v*x*3+26,26,12,v,x,1,24))or C:

i ,Y=_;j(P(’BBB’,*(lambda T:(T*80+T**9

*i-950*T **99,T*70-880*T**18+701*

T **9 ,T*i**(1-T**45*2)))(sum(

[ Y(0,(A%3/3.+X%v+(X/v+

A/3/3.-x/2)/1j)*2.5 /x -2.7,i)**2 for \

A in C

[:9]]) /9)

) )

http://preshing.com/20110926/high-resolution- mandelbrot- in-obfuscated- python/

28 / 74

(30)

Upravy obr´ ´ azk˚ u

(31)

Uprava barev ´

pro kaˇzd´y pixel:

zjisti barvu (getpixel)

uloˇz upravenou barvu (putpixel)

30 / 74

(32)

Uprava barev ´

pro kaˇzd´y pixel:

(33)

Uprava barev – k´ ´ od

def remove_green(filename):

im = Image.open(filename) im = im.convert("RGB") width, height = im.size for x in range(width):

for y in range(height):

(r, g, b) = im.getpixel((x, y)) im.putpixel((x, y), (r, 0, b)) im.show()

31 / 74

(34)

Uprava barev – obecnˇejˇs´ı ˇreˇsen´ı ´

def transform_colors(filename, f_trans):

im = Image.open(filename) im = im.convert("RGB") width, height = im.size for x in range(width):

for y in range(height):

(r, g, b) = im.getpixel((x, y))

im.putpixel((x, y), f_trans(r, g, b)) im.show()

def inversion(r, g, b):

return (255-r, 255-g, 255-b)

(35)

Zrcadlov´ y obraz

pro kaˇzd´y pixel v lev´e polovinˇe: zjisti jeho barvu (getpixel)

uloˇz barvu na pˇr´ısluˇsnou pozici v prav´e polovinˇe (putpixel)

33 / 74

(36)

Zrcadlov´ y obraz

pro kaˇzd´y pixel v lev´e polovinˇe:

zjisti jeho barvu (getpixel)

uloˇz barvu na pˇr´ısluˇsnou pozici v prav´e polovinˇe (putpixel)

(37)

Zrcadlov´ y obraz – k´ od

for x in range(width / 2):

for y in range(height):

im.putpixel((width-1-x, y), im.getpixel((x, y)))

34 / 74

(38)

Pˇreklopen´ı

prohazov´an´ı symetrick´ych bod˚u

(39)

Pˇreklopen´ı

prohazov´an´ı symetrick´ych bod˚u

35 / 74

(40)

Pˇreklopen´ı – k´ od

V pˇredchoz´ım k´odu (zrcadlov´y obraz) zmˇen´ıme tˇelo for cyklu:

tmp = im.getpixel((width-1-x, y)) im.putpixel((width-1-x, y),

im.getpixel((x, y))) im.putpixel((x, y), tmp)

(41)

Rotace

vytvoˇr nov´y obr´azek a naplˇn jej pixely podle origin´alu – vhodnˇe pozmˇenˇen´e souˇradnice

37 / 74

(42)

Rotace

vytvoˇr nov´y obr´azek a naplˇn jej pixely podle origin´alu – vhodnˇe pozmˇenˇen´e souˇradnice

(43)

Rotace – k´ od s cenzurou

def rotation(filename):

im = Image.open(filename) im = im.convert("RGB") width, height = im.size

new_im = Image.new("RGB", (height, width)) for x in range(width):

for y in range(height):

new_im.putpixel((XXX, YYY),

im.getpixel((x, y))) new_im.show()

38 / 74

(44)

Rotace – ilustrace

x y

width

height

x height-y-1

(45)

Rotace o zadan´ y ´ uhel

goniometrick´e funkce, line´arn´ı transformace, matice – aplikace (procviˇcen´ı) pojm˚u z matematiky

40 / 74

(46)

Rotace o zadan´ y ´ uhel

goniometrick´e funkce, line´arn´ı transformace, matice – aplikace (procviˇcen´ı) pojm˚u z matematiky

(47)

Kahoot

41 / 74

(48)

Kahoot: ot´ azka 6

colors = {’black’: (0, 0, 0),

’white’: (255, 255, 255),

’red’: (255, 0, 0),

’yellow’: (255, 255, 0),

’pink’: (255, 192, 203)}

names = sorted(colors.keys(),

key=lambda c: sum(colors[c])) print(", ".join(names))

(49)

Kahoot: ot´ azka 7

def make_image1(a=150):

im = Image.new("RGB", (a, a), (255, 255, 255)) for x in range(a):

for y in range(a):

if y*10 > (x-a/2)**2:

im.putpixel((x, y), (0, 0, 0)) im.show()

make_image1()

43 / 74

(50)

Kahoot: ot´ azka 8

def make_image2(a=160):

im = Image.new("RGB", (a, a), (255, 255, 255)) for x in range(a):

for y in range(a):

if (x // 20 + y // 20) % 2 == 0:

im.putpixel((x, y), (0, 0, 0)) im.show()

make_image2()

(51)

Kahoot: ot´ azka 9

def transform(filename):

im = Image.open(filename) im = im.convert("RGB") width, height = im.size for x in range(width):

for y in range(height):

(r, g, b) = im.getpixel((x, y)) g, b = int(g*0.8), int(b*0.8) r = min(int(r*1.4), 255)

im.putpixel((x, y), (r, g, b)) im.show()

45 / 74

(52)

Kahoot transformace

(53)

” Praktick´ a“ aplikace - ˇsifra

47 / 74

(54)

Histogram

variace na t´ema

”frekvenˇcn´ı anal´yza“

(55)

Histogram – textov´ y v´ ypis

0 - 19: 0.3 % 20 - 39: 3.5 % 40 - 59: 6.3 % 60 - 79: 8.3 % 80 - 99: 12.7 % 100 - 119: 17.1 % 120 - 139: 18.5 % 140 - 159: 15.2 % 160 - 179: 9.0 % 180 - 199: 4.0 % 200 - 219: 1.8 % 220 - 239: 1.1 % 240 - 259: 2.2 %

(implementace – doporuˇcen´e cviˇcen´ı)

49 / 74

(56)

Dalˇs´ı n´ amˇety na ´ upravy

zmˇena velikosti obr´azku pˇrevod do stupˇn˚u ˇsedi

rozmaz´an´ı (blur), detekce hran

... dalˇs´ı vˇeci co um´ı v´aˇs grafick´y program

(57)

Poˇr´ adek v umˇen´ı

http://www.ted.com/talks/ursus_wehrli_tidies_up_art.html

51 / 74

(58)

Poˇr´ adek (nejen) v umˇen´ı

(59)

Poˇr´ adek v umˇen´ı – pixel po pixelu

53 / 74

(60)

Razen´ı pixel˚ ˇ u podle barvy

vytvoˇr´ıme seznam vˇsech pouˇzit´ych barev – seznam trojic [(0, 150, 20), (255,255,255), (0, 0, 255), ...]

seznam seˇrad´ıme

barvy um´ıst´ıme do obr´azku

(61)

def tidy_up(filename):

im = Image.open(filename) im = im.convert("RGB") width, height = im.size pixels = []

for x in range(width):

for y in range(height):

pixels.append(im.getpixel((x, y))) pixels.sort()

new_im = Image.new("RGB", (width, height)) for y in range(height):

for x in range(width):

new_im.putpixel((x, y), pixels[y*width+x]) new_im.show()

55 / 74

(62)

Razen´ı pixel˚ ˇ u

(63)

Razen´ı pixel˚ ˇ u

pixely je seznam trojic (r, g, b) sort() pouˇz´ıv´a

”lexikografick´e“ ˇrazen´ı pokud chceme

”ˇrazen´ı dle souˇctu“ (intenzity) nahrad´ıme pixels.sort() za:

pixels = sorted(pixels,

key=lambda c: -(c[0]+c[1]+c[2]))

57 / 74

(64)

Poˇr´ adek v umˇen´ı – n´ amˇety

Zkuste dalˇs´ı zp˚usoby ˇrazen´ı:

po ˇr´adc´ıch / sloupc´ıch po ”ˇctvereˇcc´ıch“

podle jin´eho krit´eria

”gradient“ po uhlopˇr´ıˇcce

(65)

Scalable Vector Graphics (SVG)

vektorov´y form´at zaloˇzen´y na XML

snadn´y zp˚usob vytv´aˇren´ı obr´azk˚u v jak´emkoliv jazyce (generujeme prost´y text)

prohl´ıˇzen´ı: napˇr. webov´y prohl´ıˇzeˇc ruˇcn´ı editov´an´ı: napˇr. Inkscape

pˇrevod na bitmapu: napˇr. convert (ImageMagick)

59 / 74

(66)

SVG pˇr´ıklad

<svg xmlns="http://www.w3.org/2000/svg">

<line x1="15" y1="20" x2="30" y2="80"

stroke="black" stroke-width="1"/>

<circle cx="130" cy="50" r="30" stroke="blue"

stroke-width="2" fill="green" />

<polyline fill="none" stroke="red" stroke-width="4"

points="160,20 180,30 200,10 234,80"/>

</svg>

(67)

Hvˇezda

61 / 74

(68)

def star(n=10, length=100):

svg_header()

center_x = length * 1.5 center_y = length * 1.5 step = length / n

for i in range(n + 1):

svg_line(center_x + i*step, center_y, center_x, center_y + (n-i)*step) svg_line(center_x - i*step, center_y,

center_x, center_y + (n-i)*step) svg_line(center_x + i*step, center_y,

center_x, center_y - (n-i)*step) svg_line(center_x - i*step, center_y,

(69)

Kompaktnˇejˇs´ı z´ apis

def star(n=10, length=100):

svg_header()

center_x = length * 1.5 center_y = length * 1.5 step = length / n

for i in range(n + 1):

for dx, dy in [(-1, -1), (-1, 1), (1, -1), (1, 1)]:

svg_line(center_x + dx*i*step, center_y, center_x, center_y + dy*(n-i)*step) svg_finish()

63 / 74

(70)

Variace na hvˇezdu

(71)

Vlastn´ı knihovna pro ˇzelv´ı grafiku

ˇzelv´ı grafika – pouˇz´ıv´ana knihovna turtle vytvoˇrme vlastn´ı

”knihovnu“ s vykreslov´an´ım do SVG jen z´akladn´ı pˇr´ıkazy:

forward(length)

left(angle), right(angle) save(filename)

65 / 74

(72)

Princip implementace

stav ˇzelvy: souˇradnice x, y a aktu´aln´ı natoˇcen´ı heading vykreslen´y obrazec: seznam souˇradnic

(73)

Implementace I

x = 50 y = 50 heading = 0 lines = []

def left(angle):

global heading heading -= angle def right(angle):

global heading heading += angle

67 / 74

(74)

Implementace II

def forward(d):

global x global y

nx = x + d * math.cos(heading * math.pi / 180) ny = y + d * math.sin(heading * math.pi / 180) lines.append((x, y, nx, ny))

x, y = nx, ny

(75)

Implementace III

def save(filename):

f = open(filename, "w") f.write("<svg>")

s = ’<line x1="{}" y1="{}" x2="{}" y2="{}" style="{}" />’

for x1, y1, x2, y2 in lines:

f.write(s.format(x1, y1, x2, y2,

"stroke:black;stroke-width:1")) f.write("</svg>")

f.close()

69 / 74

(76)

Pozn´ amky

jde o n´azornou uk´azku princip˚u, nikoliv dobrou knihovnu:

pˇr´ıliˇs mal´a funkcionalita chyb´ı dokumentace

nevhodn´e pouˇzit´ı glob´aln´ıch promˇenn´ych – lepˇs´ı pˇres objektovou reprezentaci

(77)

class Turtle:

def __init__(self):

self.x = 50 self.y = 50 self.heading = 0 self.lines = []

def left(self, angle):

self.heading -= angle

def right(self, angle):

self.heading += angle

def forward(self, d):

nx = self.x + d * math.cos(self.heading * math.pi / 180) ny = self.y + d * math.sin(self.heading * math.pi / 180) self.lines.append((self.x, self.y, nx, ny))

self.x, self.y = nx, ny

71 / 74

(78)

Absolutn´ı vs relativn´ı vykreslov´ an´ı

(souˇradnice vs ˇzelva)

(79)

Jak vykresl´ıte tyto obr´ azky?

73 / 74

(80)

Shrnut´ı

uk´azka element´arn´ı pr´ace s grafikou bitmapov´a – Image, putpixel, getpixel vektorov´a – SVG, line

vyuˇzit´ı z´akladn´ıch konstrukc´ı (vesmˇes vnoˇren´e for cykly), trocha matematiky

Cytaty

Powiązane dokumenty

CLP – Constraint Logic Programming Ovlivnˇ en´ı efektivity prohled´ av´ an´ı s navracen´ım. Ovlivnˇ en´ı efektivity prohled´ av´ an´ı

stˇredn´ı arteri ´alnm´ı tlak (mean arterial pressure) CVP.. centr ´aln´ı ˇziln´ı tlak (central

uˇcen´ı je potˇrebn´e pro nezn´am´e prostˇred´ı (a l´ın´e analytiky ,) uˇc´ıc´ı se agent – v´ykonnostn´ı komponenta a komponenta uˇcen´ı metoda uˇcen´ı

I Zaveden´ı n´ ahodn´ e veliˇ ciny slouˇ z´ı zejm´ ena ke zkr´ acen´ı a zpˇrehlednˇ en´ı z´ apisu pravdˇ epodobnost´ı... Tato funkce m´ a n´

zdravotn´ıch sestr ´ach - person ´aln´ı obsazen´ı, vzd ˇel ´an´ı, pˇresˇcasy, nevykonan ´a zdravotn´ı p ´eˇce.. pacientech - spokojenost se zdravotn´ı p

Pˇri ˇreˇsen´ı soustav s parametrem pomoc´ı GEM mus´ıme b´ yt velmi opatrn´ı na prov´ adˇ en´ı element´ arn´ıch ´ uprav.. Pro soustavy se ˇ ctvercovou matic´ı

I Aby mohla molekula absorbovat infraˇ cerven´ e z´ aˇren´ı mus´ı bˇ ehem vibrace doch´ azet ke zmˇ enˇ e dip´ olov´ eho momentu.. I Pˇri absorpci doch´ az´ı ke zmˇ enˇ

Z´ aludnosti: Promˇ enn´ e, pamˇ et’, rekurze Pr´ ace se soubory, textem, regul´ arn´ı v´ yrazy Sloˇ zen´ e datov´ e typy, objekty v Pythonu Obr´ azky (reprezentace,