skrypt
Transkrypt
skrypt
Wprowadzenie do środowiska Matlab na potrzeby przedmiotu Komputerowe Przetwarzanie Obrazu Instytut Modelowania Komputerowego Politechnika Krakowska Ustawianie ścieżki do katalogów Dostęp do katalogów ustawia się w oknie Path Browser wywołanym przez File/Set Path. Save Path zapisuje modyfikacje ścieżek do pliku pathdef.m. Definicja zmiennych, wektorów i macierzy W Matlabie podstawową forma reprezentacji zmiennych jest macierz. Obejmuje to macierze jednowymiarowe (czyli wektory), macierze wielowymiarowe jak również macierz zmienne skalarne, które reprezentowane są jako macierz 1x1. Przykład 1: >> x = 22 x= 22 >> whos Name Size x Bytes Class 1x1 8 double array Grand total is 1 element using 8 bytes >> Zmienna x jest reprezentowana jako macierz 1x1. Przykład 2: wektor poziomy >> y = [1 2 3 4] y= 1 2 3 >> whos y Name Size y 1x4 4 Bytes Class 32 double array Grand total is 4 elements using 32 bytes Przykład 3: wektor pionowy >> y = [1 ; 2 ; 3 ; 4] y= 1 2 3 4 >> whos y Name Size y Bytes Class 4x1 32 double array Grand total is 4 elements using 32 bytes lub przez transpozycję, którą w Matlabie zapisujemy jako ' (apostrof) >> z = [1 2 3 4] z= 1 2 3 4 >> z = z' z= 1 2 3 4 Można też: >> z2 = [1 2 3 4]' z2 = 1 2 3 4 Tworzenie macierzy dwuwymiarowych. Przykład 4: macierz pusta >> m = [] m= [] Przkład: macierz 3x4 >> m = [1 2 3 4 ; 5 6 7 8 ; 9 10 11 12] m= 1 5 9 2 6 10 3 4 7 8 11 12 Poszczególne wiersze oddzielone są średnikiem. Bardzo często przydatne są też funkcję tworzące macierze pewnego typu. eye(... , ...) tworzy macierz jednostkową (z jedynkami na diagonali) >> eye(3,3) ans = 1 0 0 0 1 0 0 0 1 Inne podobne funkcje, których znaczenie jest oczywiste, to: >> ones(2,3) ans = 1 1 1 1 1 1 >> zeros(3,2) ans = 0 0 0 0 0 0 >> rand(2,2) ans = 0.9501 0.2311 0.6068 0.4860 >> randn(2,2) ans = -0.4326 -1.6656 0.1253 0.2877 rand(...) zwraca macierz z losowymi wartościami o rozkładzie równomiernym, a randn(...) o rozkładzie normalnym. Zmienna ans zawsze przechowuje wynik ostatniej operacji. Odnoszenie się do pojedynczych elementów macierzy odbywa się poprzez indeksy. >> x = rand(2,3) x= 0.8913 0.7621 0.4565 0.0185 0.8214 0.4447 >> x(1, 2) ans = 0.4565 Indeksowanie jest od 1 a nie od zera ! Przypisanie wartości jest analogiczne: >> x(1, 2) = 222 x= 0.8913 222.0000 0.8214 0.7621 0.0185 0.4447 Można również posługiwać się zakresami, zarówno podczas tworzenia macierzy jak i odnoszenia się do ich elementów. Przykład 5: wektor z elementami od 1 do 10 >> v = 1:10 v= 1 2 3 4 5 6 7 8 9 10 Przykład 6: wektor z elementami od 1 do 10 z krokiem 0.8 >> v = 1:0.8:10 v= 1.0000 1.8000 2.6000 3.4000 4.2000 5.0000 5.8000 6.6000 7.4000 8.2000 9.0000 9.8000 Podobnie dla macierzy: >> m = [ 1:2:10 ; 2:0.5:4] m= 1.0000 2.0000 3.0000 2.5000 5.0000 3.0000 7.0000 3.5000 9.0000 4.0000 Jeśli z macierzy chcemy pobrać np. drugą kolumnę lub trzeci wiersz, możemy napisać: >> x = rand(3,4) x= 0.6154 0.7919 0.9218 0.7382 0.1763 0.4057 0.9355 0.9169 0.4103 0.8936 0.0579 0.3529 0.4103 0.3529 >> y = x(:,2) y= 0.7382 0.1763 0.4057 >> z = x(3,:) z= 0.9218 0.4057 Albo bardziej skomplikowany „wycinek” z macierzy, np. wiersze od 2 do 4 oraz kolumny od 3 do 5: >> x = rand(5,6) x= 0.8132 0.0099 0.1389 0.2028 0.1987 0.6038 0.2722 0.1988 0.0153 0.7468 0.4451 0.9318 0.4660 0.4186 0.8462 >> y = x(2:4,3:5) y= 0.9318 0.4660 0.4186 0.2026 0.6721 0.8381 0.3795 0.8318 0.5028 0.5252 0.2026 0.6721 0.8381 0.0196 0.6813 0.3795 0.8318 0.5028 0.7095 0.4289 0.3046 0.1897 0.1934 0.6822 W podobny sposób można robić również podstawienia: >> x = rand(2,3) x= 0.3028 0.5417 0.1509 0.6979 0.3784 0.8600 >> y = [ 22 22 22 ] y= 22 22 22 >> x(1,:) = y x= 22.0000 22.0000 22.0000 0.5417 0.6979 0.8600 Można też usunąć np. drugi wiersz danej macierzy w taki sposób: >> x = rand(3,4) x= 0.1365 0.0118 0.8939 0.1991 0.2987 0.6614 0.2844 0.4692 0.0648 0.9883 0.5828 0.4235 0.2844 0.0648 0.9883 0.4235 >> x(2,:) = [] x= 0.1365 0.8939 0.1991 0.6614 Co się stanie, jeśli macierz x przypiszemy do zmiennej y a następnie zmienimy wartości elementów w y? Czy zmiana jest widoczna w x? Inaczej rzecz ujmując, czy operacja y = x dokonuje „głębokiej” kopii x, czy tylko kopuje referencje do x? >> x = zeros(3) x= 0 0 0 0 0 0 >> y = x 0 0 0 y= 0 0 0 0 0 0 0 0 0 >> y(1,1) = 22 y= 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 >> x x= 0 0 0 Operacje na macierzach. Dwie macierze można pomnożyć, jeśli mają odpowiednie wymiary, tzn. jeśli liczba kolumn pierwszej jest równa liczbie wierszy drugiej. Przykład 7: >> x = rand(3,2) x= 0.8537 0.5936 0.4966 0.8998 0.8216 0.6449 >> y = rand(2,4) y= 0.8180 0.6602 0.3420 0.2897 0.3412 0.5341 0.7271 0.3093 0.7718 0.6413 0.5139 0.8990 0.6857 0.5605 >> z = x * y z= 1.2923 1.0280 0.8320 0.5526 0.4410 0.3567 Natomiast: >> x = rand(3,2) x= 0.8385 0.5681 0.3704 0.7027 0.5466 0.4449 >> y = rand(3,4) y= 0.6946 0.6213 0.7948 0.9568 0.5226 0.8801 0.1730 0.9797 0.2714 0.2523 0.8757 0.7373 >> z = x * y ??? Error using ==> * Inner matrix dimensions must agree. Pewnym wyjątkiem jest macierz 1x1, która reprezentuje wartość skalarną: >> a = 22 a= 22 >> x = ones(3) x= 1 1 1 1 1 1 1 1 1 >> x = a*x x= 22 22 22 22 22 22 22 22 22 Jak widać, każdy element macierzy został pomnożony przez wartość 22. Oprócz operacji macierzowych, przez dodanie . (kropki) przy znaku działania, możemy wykonać dane działanie element po elemencie. Porównaj na przykład operacje macierzową mnożenia: >> x = 2 * ones(2) x= 2 2 2 2 >> y = 3 * ones(2) y= 3 3 3 3 >> z = x * y z= 12 12 12 12 >> z = x .* y z= 6 6 6 6 Inny przykład – chcemy każdy element macierzy (a nie całą macierz) podnieść do potęgi 3: >> x = 2 * ones(2) x= 2 2 2 2 >> x = x .^ 3 x= 8 8 8 8 Podczas gdy podniesienie macierzy do potęgi 3 daje: >> x = 2 * ones(2) x= 2 2 2 2 >> x = x^3 x= 32 32 32 32 Inne operacje na macierzach A(:,end) - wypisanie ostatniej kolumny A(end,:) - ostatni wiersz size(A) – pobieranie rozmiaru macierzy >> x = rand(3,4) x= 0.9901 0.7889 0.4387 0.4983 0.2140 0.6435 0.3200 0.9601 0.7266 0.4120 0.7446 0.2679 >> size(x) ans = 3 4 >> [wiersze, kolumny] = size(x) wiersze = 3 kolumny = 4 Tablice wielowymiarowe. Można również pracować z macierzami w większej niż 2 liczbie wymiarów. >> x = ones(2,3, 2) x(:,:,1) = 1 1 1 1 1 1 x(:,:,2) = 1 1 1 1 1 1 >> x(:,:,2) = x(:,:,2) * 22 x(:,:,1) = 1 1 1 1 1 1 x(:,:,2) = 22 22 22 22 22 22 >> x(2,1,1) = 333 x(:,:,1) = 1 1 1 333 1 1 x(:,:,2) = 22 22 22 22 22 22 Operacje arytmetyczne: Dodawanie C=A+B dodawanie Odejmowanie analogicznie Mnożenie tablic „*” C = A * B mnożenie macierzy (suma iloczynów i-tego wiersza macierzy A i k-tej kolumny macierzy B) C=A.*B operacja tablicowa (mnożenie elementów o tych samych indeksach) Dzielenie Analogicznie W rachunku tablicowym C=A./B Potęgowanie C=A.^2 podniesienie do kwadratu Pierwiastkowanie C=sqrt(A) Operacje transponowania „’ ”, operacje odwracania „inv” Transpozycja macierzy A.’ Macierz odwrotna C=inv(B) < <= > >= == ~= & | ~ Xor Przykład 8: A<B A<=B A>B A>=B A==B A~=B and(A,B) or(A,B) not(A) xor(A,B) Mniejszy od Mniejszy lub równy Większy od Większy lub równy Równy Różny od AND – iloczyn logiczny OR – suma logiczna NOT - negacja EXCLUSIVE OR – suma rozłączna >> x = rand(2,3) x= 0.0164 0.1901 0.5869 0.0576 0.3676 0.6315 >> y = rand(2,3) y= 0.7176 0.6927 0.0841 0.4544 0.4418 0.3533 >> x < y ans = 1 1 0 1 1 0 Jedynki wskazują te elementy, dla których warunek jest TRUE. Inne operacje: any(A) – zwraca 1 jeżeli któryś z elementów kolumny jest niezerowy all(A)- zwraca 1 jeżeli wszystkie elementy kolumny są niezerowe find – wyszukuje elementy spełniające dany warunek logiczny i „all” oraz „any” działają na kolumnach macierzy lub w przypadku wielowymiarowej – na pierwszym niejednoelementowym wymiarze Przykład 9: wyzerować elementy w x większe od 0.5 x= 0.1536 0.6756 0.6992 0.7275 0.4784 0.5548 >> indx = find( x > 0.5 ) indx = 2 3 4 6 >> x(indx) = 0 x= 0.1536 0 0 0 Lub krócej: x= 0.4784 0 0.1210 0.4508 0.7159 0.8928 0.2731 0.2548 >> x( find(x>0.5) ) = 0 x= 0.1210 0.4508 0 0 0.2731 0.2548 Zadanie: Dla dwóch macierzy o tym samym rozmiarze wyzeruj elementy na tych pozycjach, na których się różnią. Zadanie: Wypróbuj następujące funkcje: Zaokrąglenia Wprowadzić wektor x = [2.2, -3.6; -4.7, 8.1] ceil (x) % zaokrąglenie w górę ans = 3 -3 -4 9 fix(x) % zaokrąglenie przez odcięcie ans = 2 -3 -4 8 floor(x) % w dół ans = 2 -4 -5 8 round(x) % do najbliższej całkowitej ans = 2 -4 -5 8 abs(x) % wartość bezwzględna ans = 2.2000 3.6000 4.7000 8.1000 Budowa skryptu (tzw. M-pliku) Plik zawierający skrypt Matlaba (m-plik) to zwykły plik tekstowy zapisany z rozszerzeniem .m. Może zawierać sekwencje poleceń Matlab’a lub/i wywołania innych m-plików Może wywoływać sam siebie. Są dwa rodzaje plików: skryptowe i funkcyjne. Skryptowe zawierają ciągi poleceń i działają na zmiennych dostępnych w przestrzeni roboczej mogą służyć do wprowadzania większej ilości danych, zapisu wyników, uproszczenia powtarzających się sekwencji, zapisu algorytmów. Mogą powstać konflikty nazw zmiennych w przestrzeni roboczej. Funkcyjne - algorytm funkcji na zmiennych lokalnych lub globalnych z przestrzenią roboczą Komunikują się przez zmienne globalne (definiowane poleceniem „global”) lub/i parametry formalne muszą zaczynać się od „function”. function[lista argumentów wyjściowych]=nazwa_funkcji(lista argumentów wejściowych) Argumenty wejściowe i wyjściowe mają charakter lokalny. Nawias [] opuszcza się jeżeli jest jeden lub brak parametrów wyjściowych. Przykład 10: Zapisać jako pitagoras.m Funkcja pitagoras zwraca jedną wartość, mianowicie c. Zwróć uwagę, że a, b oraz c mogą być macierzami. Przykład wywołania: >> x = pitagoras(3,4) temp = 25 c= 5 x= 5 A dla macierzy otrzymamy również poprawny wynik: >> a = [1 2; 3 4] a= 1 3 2 4 >> b = [2 3; 4 5] b= 2 4 3 5 >> x = pitagoras(a,b) temp = 5 13 25 41 c= 2.2361 5.0000 3.6056 6.4031 x= 2.2361 5.0000 3.6056 6.4031 Przykład funkcji, która nic nie zwraca. Pokazuje również jak wypisywać tekst oraz pobierać dane z klawiatury. >> hello(3) hello, przeslales 3.000000 podaj nowa wartosc:22 x= 22 nacisnij cos by zakonczyc... do widzenia! Zadanie: Sprawdź co się stanie po wywołaniu: >> x = 33 x= 33 >> hello(x) hello, przeslales 33.000000 podaj nowa wartosc:22 x= 22 nacisnij cos by zakonczyc... do widzenia! >> x ..... Jaka będzie wartość x? Czy zmiana na 22 wewnątrz funkcji zmieniła wartość x w miejscu wywołania czy zmieniła tylko kopie lokalną? Jaka będzie sytuacja, jeśli funkcja otrzyma macierz? Czy też wykona kopię głęboką tej macierzy? Oto funkcja, która zwraca dwie wartości (analogicznie jest dla trzech i więcej). Średnik na końcu linijki oznacza brak wypisania wyniku operacji na konsoli. Wywołanie: >> a = 3*ones(2) a= 3 3 3 3 >> b = 2*ones(2) b= 2 2 2 2 >> [xx yy] = mojafunkcja(a,b) xx = 6 6 yy = 6 6 5 5 5 5 Korzystanie z help'a: >> help mojafunkcja To jest opis funkcji A teraz krótki skrypt, który nie definiuje żadnej funkcji, ale za to pozwala zapisać i wykonać kilka operacji razem – w tym przypadku narysujemy wykres funkcji sinus oraz cosinus. Wywołanie: >> sinus Zmienne globalne (dostępne wszędzie – nawet w funkcjach) definiuje się za pomocą słowka global. Typy zmiennych w Matlabie Programowanie Słowa kluczowe >> iskeyword ans = 'break' 'case' 'catch' 'continue' 'else' 'elseif' 'end' 'for' 'function' 'global' 'if' 'otherwise' 'persistent' 'return' 'switch' 'try' 'while' if, else, elseif if logical_expression statements end Np. if n < 0 % If n negative, display error message. disp('Input must be positive'); elseif rem(n,2) == 0 % If n positive and even, divide by 2. A = n/2; else A = (n+1)/2; % If n positive and odd, increment and divide. end switch switch expression (scalar or string) case value1 statements % Executes if expression is value1 case value2 statements % Executes if expression is value2 . otherwise statements % Executes if expression does not match any case end Np. switch input_num case -1 disp('negative one'); case 0 disp('zero'); case 1 disp('positive one'); otherwise disp('other value'); end while while expression statements end Np. n = 1; while prod(1:n) < 1e100 n = n + 1; end for for index = start:increment:end statements end Np. for i = 1:m for j = 1:n A(i,j) = 1/(i + j - 1); end end continue Np. fid = fopen('magic.m','r'); count = 0; while ~feof(fid) line = fgetl(fid); if isempty(line) | strncmp(line,'%',1) continue end count = count + 1; end disp(sprintf('%d lines',count)); break Np. fid = fopen('fft.m','r'); s = ''; while ~feof(fid) line = fgetl(fid); if isempty(line) break end s = strvcat(s,line); end disp(s) Proste przykłady z przetwarzania obrazu Wpisz help imread aby sprawdzić jakie typy plików graficznych obsługuje Matlab. Przykład 11: m-plik simple_image_proc.m imfinfo('portret.jpg') disp('dalej...'); pause im = imread('portret.jpg'); imshow(im) disp('dalej...'); pause disp('zmiana mapy kolorow na hsv'); colormap(hsv) disp('dalej...'); pause disp('zmiana mapy kolorow na jet'); colormap(jet) disp('dalej...'); pause disp('zmiana mapy kolorow na losowa o 2 barwach'); colormap( rand(2,3) ) disp('dalej...'); pause disp('zmiana mapy kolorow na losowa o 4 barwach'); colormap( rand(4,3) ) disp('dalej...'); pause disp('zmiana mapy kolorow na losowa o 8 barwach'); colormap( rand(8,3) ) disp('dalej...'); pause disp('zmiana mapy kolorow na losowa o 12 barwach'); colormap( rand(12,3) ) disp('dalej...'); pause disp('koniec...'); Przykład 12: m-plik simple_image_proc2.m imfinfo('e0102.bmp') disp('dalej...'); pause im = imread('e0102.bmp'); imshow(im) disp('dalej...'); pause disp('tylko skladowa czerwona jako czarno-biala') imshow(im(:,:,1)) disp('dalej...'); pause disp('tylko skladowa zielona jako czarno-biala') imshow(im(:,:,2)) disp('dalej...'); pause disp('tylko skladowa niebieska jako czarno-biala') imshow(im(:,:,3)) disp('dalej...'); pause disp('tylko skladowa czerwona z mapa kolorow') imshow(im(:,:,1)) map = zeros(256, 3) map(:,1) = [0:(1/255):1]' colormap(map) disp('dalej...'); pause disp('tylko skladowa zielona z mapa kolorow') imshow(im(:,:,2)) map = zeros(256, 3) map(:,2) = [0:(1/255):1]' colormap(map) disp('dalej...'); pause disp('tylko skladowa niebieska z mapa kolorow') imshow(im(:,:,3)) map = zeros(256, 3) map(:,3) = [0:(1/255):1]' colormap(map) disp('dalej...'); pause disp('koniec'); Sprawdzanie typu obrazu: isbw(A) – sprawdza, czy obraz jest binarny isgray(A) – sprawdza, czy obraz jest obrazem o poziomach szarości isind(A) – sprawdza, czy obraz jest opisany macierzą indeksów isrgb(A) – sprawdza, czy obraz jest obrazem rgb Inne informacje Znaki specjalne = przypisanie wartości [ ] tworzenie tablic, argumenty wyjściowe funkcji, łączenie macierzy (deklar. wartości, po=] { }indeksy struktur i tablic komórkowych ( ) argumenty wejściowe funkcji, indeksy tablic, nawiasy potrzebne do określenia kolejności działań (nigdy po =,<,>) . kropka dziesiętna, separator nazw obiektów, zamiana operacji macierzowej na tablicową … kontynuacja polecenia w następnym wierszu , separator poleceń, indeksów, argumentów funkcji ; koniec wiersza macierzy, wstrzymanie wypisania wyniku % początek komentarza : generowanie wektorów, indeksowanie macierzy, ‘ łańcuch (apostrof przed i po), operator transpozycji macierzy (po) lub sprzężenia Predefiniowane stałe Inf (infinitive) to ∞ 1/0 log(0) Uwaga: Inf-Inf and Inf/Inf dają w wyniku NaN (Not-a-Number) NaN (Not-a-Number) Wynik każdej operacji na NaN, np sqrt(NaN) (+Inf)+(-Inf) 0*Inf 0/0 oraz Inf/Inf Uwaga: Dwie NaN nie są sobie równe, zatem operacja logiczne na NaN dają zawsze 0 (fałsz), za wyjątkiem ~= (różny, nie równy) NaN ~= NaN ans = 1 NaN == NaN ans = 0 NaN-y w wektorze traktowane jako różne niepowtarzalne elementy unique([1 1 NaN NaN]) %znajdź różne elementy wektora ans = 1 NaN NaN isnan([1 1 NaN NaN]) % isnan służy do wykrywania NaN w macierzy, zwraca 1, jeżeli jest gdzieś NaN ans = 0 0 1 1