Zapisz jako PDF

Transkrypt

Zapisz jako PDF
Ćwiczenia z przetwarzania tablic 2D
Wyświetlanie tablic 2D
Jako wstęp do przetwarzania obrazów w pythonie przećwiczmy podstawowe operacje na
dwuwymiarowych tablicach numpy w postaci których będziemy takie obrazy przechowywać.
Zacznijmy od zdefiniowania przykładowej tablicy, która będzie reprezentować obrazek.
import numpy as np
import pylab as py
a=np.zeros((100,100),dtype=np.bool)
a[30:50,30:50]=True
a[50:70,50:70]=True
Stworzyliśmy w ten sposób tablice 100 na 100 z wpisanymi wartościami False oraz w środku dwa
kwadraty o boku 20 z wartościami True. Już tak stworzoną tablicę możemy wyświetlić za pomocą
pylaba.
py.imshow(a)
py.show()
Nie do końca można było się spodziewać, że pylab wyświetli wartości False w kolorze granatowym, a
wartości True w kolorze bordowym. Za przyporządkowanie kolorów określonym wartościom
odpowiada tzw. mapa kolorów, którą podajemy jako parametr w poleceniu imshow. Aby uzyskać
bardziej intuicyjną skalę szarości należy wywołać polecenie następująco
py.imshow(a,cmap = py.cm.gray)
py.show()
Teraz kolory (a raczej ich brak) są takie jakich można było się spodziewać. Zaskakujące jest za to
rozmycie brzegów kwadratów. Obrazek wyświetlany jest w większych rozmiarach niż jego domyślne
100 na 100 pixeli. Pylab aby wyświetlić go w wyższej rozdzielczości musi zwiększyć jego rozmiary.
Rozciągając obrazek można w różny sposób przypisywać wartości pixelom, których nie było w
pierwotnym obrazku. Proces ten nazywamy interpolacją i aby uzyskać "ostre" krawędzie należy znów
użyć odpowiedniej opcji metody imshow.
py.imshow(a,cmap = py.cm.gray, interpolation = 'nearest')
py.show()
Gra w życie Conwaya
W ramach ćwiczeń zaprogramujmy klasyczny automat komórkowy zwany grą w życie Conwaya. W
naszej wersji gra toczy się na skończonej planszy o wymiarach 100 na 100 podzielonej na
kwadratowe komórki. Każda komórka (poza brzegowymi) ma ośmiu sąsiadów, czyli komórki
przylegające do niej bokami i rogami. Każda komórka może znajdować się w jednym z dwóch stanów:
może być albo "żywa" (stanowi przypisujemy wartość 1), albo "martwa" (wartość 0). Stan wszystkich
komórek w pewnej jednostce czasu jest używany do obliczenia stanu wszystkich komórek w
następnej jednostce. Po obliczeniu wszystkie komórki zmieniają swój stan jednocześnie. Stan
komórki zależy tylko od liczby jej żywych sąsiadów w następujący sposób
Martwa komórka, która ma dokładnie 3 żywych sąsiadów, staje się żywa w następnej jednostce
czasu (rodzi się)
Żywa komórka z 2 albo 3 żywymi sąsiadami pozostaje żywa, przy innej liczbie sąsiadów umiera
Zacznijmy od zdefiniowania planszy gry
import numpy as np
import pylab as py
a=np.zeros((100,100))
Kluczową i najtrudniejszą funkcją jest funkcja zliczająca liczbę sąsiadów danej komórki.
Problematyczne jest tutaj uwzględnienie przypadku komórek znajdujących się na rogach, które mają
po trzech sąsiadów, oraz komórek brzegowych mających po 5 sąsiadów. Przykładowe rozwiązanie
wygląda następująco.
def ile_sasiadow(x,y,macierz):
return
np.sum(macierz[max(,x-1):min(macierz.shape[],x+2),max(,y-1):min(macierz.shape
[1],y+2)].flatten())-macierz[x,y]
Z tak przygotowaną funkcją ile_sasiadow możemy zdefiniować funkcję określającą logikę gry w
życie.
def nowy_stan_komorki(x,y,macierz):
sasiadow=ile_sasiadow(x,y,macierz)
if sasiadow==3: return 1
if sasiadow==2 and macierz[x,y]==1: return 1
return
Możemy teraz zdefiniować nowy stan całej planszy.
def krok(macierz):
wynik=macierz.copy()
for x,y in np.ndindex(wynik.shape):
wynik[x,y]=nowy_stan_komorki(x,y,macierz)
return wynik
Jako warunku początkowego możemy użyć tzw. lokomotywy.
lokomotywa=np.array([[1,1,1,,1],[1,,,,],[,,,1,1],[,1,1,,1],[1,,1,,1]])
a[45:50,45:50]=lokomotywa
W pylabie istnieje prosty sposób na wyświetlenie animacji poprzez odświeżanie już wyświetlonego
obrazka.
py.ion()
for n in range(1000):
py.imshow(a, cmap='Greys',
a=krok(a)
py.draw()
interpolation='nearest')
"Programowanie dla Fizyków Medycznych"