Analiza i przetwarzanie obrazów W. 1 – 2007-10-08

Podstawy MatLaba

Znak zachęty >>

porzez ten znak wprowadza się wszystkie wyrażenia w aplikacji.

Podstawowe wyrażenia

Podstawowym wyrażeniem jest przypisanie wartości do zmiennej:

>> a = 20

W tym momencie zainicjowana została zmienna a, która jest macierzą, w tym przypadku o rozmiarze 1x1.

W Matlabie rozróżniana jest wielkość znaków, więc:

>> a = 20;

jest różne od

>> A = 20;

Ogólnie można powiedzieć, że praca w Matlabie polega na pracy z macierzami

– wszystkie dane zapisywane są w różnej postaci, ale zawsze jest to traktowane jako wektor/macierz.

Fakt ten ma wpływ na prawidłowe rozróżnianie stosowanych operatorów.

Wyświetlanie zmiennych w obszarze roboczym Matlaba Możliwość taką umożliwia polecenie

>> whos //bez średnika

Wyświetlane są zmienne wraz z ich rozmiarem oraz typem – typ danych jest istotny na przetwarzanie obrazów.

Wprowadzanie macierzy do programu

Wprowadzanie macierzy przebiega wg schematu:

>> nazwaMacierzy = [war1 war 2 ; war3 war4]

Powstaje wówczas macierz:

⎡

1

war

war 2 ⎤

⎢

⎥

⎣ war 3 war 4⎦

kolumny oddzielamy spacjami bądź przecinkami (przecinek nie jest separatorem dziesiętnym przy liczbach); wiersze oddzielamy średnikiem Ważną rzeczą przy pracy z macierzami w MatLabie jest to, że wiersze i kolumny są liczone od 1 (a nie od 0).

1

Podstawowe manipulacje na macierzach Transpozycja macierzy – stosujemy pojedyńczy apostrof:

>> A = [2 3 ; 4 5]

>> B = A’ // stosujemy apostrof

Obliczenie wyznacznika macierzy – wykorzystujemy funkcję det(M):

>> wznMac = det(A) // w wyniku macierz 1x1

Wyznaczenie macierzy odwrotnej do danej – funkcja inv(M):

>> Aodwr = inv(A) // w wyniku macierz taka jak A, o ile istnieje odwr.

Sumowanie elementów macierzy

Do sumowania używamy funkcji sum(M).

Podstawowa wersja tej komendy zwraca wektor, którego elementami są sumy poszczególnych kolumn:

>> sumy = sum(A) // w wyniku wektor

sumy = 6 8

Redukowanie macierzy (el. Gaussa):

Stosujemy polecenie rref(M):

>> B = rref(A)

B =

1 0

0 1

Konkatenacja macierzy

Ważna możliwość, pozwala łączyć ze sobą macierze – muszą być one zgodne albo ilością wierszy albo ilością kolumn.

Mamy dwie macierze:

⎡1 2⎤

⎡1 2

⎤

A =

B =

3

⎢

⎥

⎢

⎥

⎣3 4⎦

⎣3 4 5⎦

Macierze te są zgodne pod względem ilości wierszy, więc możliwe jest ich skonkatenowanie poziome. Nie możliwa jest konkatenacja pionowa. (różna liczba kolumn)

Konkatenację macierzy wykonuje się w sposób analogiczny do poniższego:

>> LC = [A,B]

Wynik:

⎡1 2 1 2

⎤

3

⎢

⎥

⎣3 4 3 4 5⎦

2

Obracanie macierzy

Polega na obróceniu macierzy albo w poziomie – wtedy ostatnia kolumna starej macierzy jest pierwszą kolumną nowej, przedostatnia starej macierzy jest drugą w nowej itd; albo w pionie – tutaj sytuacja jest analogiczna.

Mamy macierz A którą obracamy w poziomie:

>> A = [1 2 3 ; 2 4 6 ; 3 6 9]

⎡1 2 3⎤

⎢

⎥

⎢2 4 6⎥

⎢3 6 9⎥

⎣

⎦

>> obrA = A(3:-1:1)

⎡3 2

⎤

1

⎢

⎥

⎢6 4 2⎥

⎢9 6 3⎥

⎣

⎦

Pamiętać należy, że w przypadku cofania, trzeba podać skok o wartości ujemnej.

OPERATORY ALGEBRY LINIOWEJ

Poniższe operatory stosuje się tak, jak sie stosuje przy działaniach na macierzach (a nie przy działaniach na elementach macierzy – innymi słowy: operatory poniższe muszą spełniać zasady algebry liniowej): Dodawanie:

+

Odejmowanie:

–

Mnożenie:

*

Dzielenie: /

Dzielenie lewostronne: \

Potęgowanie:

^

Transpozycja:

‘

Mamy dwie macierze:

⎡2 3⎤

⎢

⎥

⎡10 11 12⎤

A = 4 5

B =

⎢

⎥

⎢

⎥

⎣12 13 14⎦

⎢6 7⎥

⎣

⎦

W tym wypadku nie powiodą się operacje:

>> X = A + B

>> X = A – B

>> X = A / B

>> X = A \ B

>> X = A^B

3

Jedyna dozwolona operacja to mnożenie – w tym przypadku ilość wierszy w pierwszej macierzy jest równa ilości kolumn w drugiej – zgodnie z zasadami algebry.

Wsystkie operacje są dozwolone na macierzach o równej ilości wierszy i kolumn.

Często jednak zamiast wykonywania operacji na macierzach, potrzebne jest wykonanie operacji na elementach macierzy w sposób naturalny – np. możemy chcieć przemnożyć elementy jednej macierzy przez elementy drugiej.

Do tego celu stosujemy poniższe operatory:

OPERATORY SKALARNE

Dodawanie:

+

// dodawanie sie nie zmienia

Odejmowanie:

–

//

odejmowanie

również

Mnożenie:

.*

Dzielenie: ./

Dzielenie lewostronne: .\

Potęgowanie:

.

Transpozycja:

.‘

Ważne jest, by macierze miały jednakowe wymiary.

Wymnożenie na przykład takich macierzy:

[1]

[2]

[3]

oraz [1 2 3]

nie będzie możliwe, CHYBA ŻE zastosujemy transpozycję do którejś z nich:

>> iloczyn = [1 2 3] .* [1 ; 2 ; 3]’

w wyniku powstaje wektor

iloczyn = [1 4 9]

OPERATOR :

Operator ten jest jednym z podstawowych operatorów.

Stosuje się go do:

1. utworzenia wektora składającego się z określonych elementów:

>> wek1 = 1:5

powstaje wektor:

wek1 = [1 2 3 4 5]

Powstał wektor (wierszowy) składający się z liczb od 1 do 5 ze skokiem domyślnym równym 1.

Aby zmienić skok domyślny, stosujemy dodatkową liczbę: 4

>> wek2 = 1:0.5:5

powstaje wektor:

wek2 = [1 1.5 2 2.5 3 3.5 4 4.5 5]

W zapisie tym określiśmy: element początkowy równy 1, wartość skoku 0.5, oraz element końcowy 5.

Idea takiego zapisu: [elPoczątkowy]:[skok]:[elKońcowy]

2. odnoszenia się do elementów macierzy

Bardzo ważne zastosowanie.

Przykładowo, stwórzmy macierz A:

>> A = [2 5 7 ; 4 1 2]

⎡2 5 7⎤

A = ⎢

⎥

⎣4 1 2⎦

W tym momencie odwołanie do poszczególnych elementów macierzy jest proste i polega na wykonaniu instrukcji:

>> wybrany_element = A(i,j) // zwraca skalar Przykład:

>> wybrany_element = A(2,3)

wybrany_element = 2

Odwołujemy się do i-tego wiersza i j-tej kolumny. (w tym przypadku do 2

wiersza i 3 kolumny)

Operator : pozwala na bardziej elastyczne docieranie do danych. Stosując ten operator, możemy np. dostać się do całej kolumny nr 2 w powyższej macierzy:

>> kolumna_dwa = A(:,2) // zwraca wektor wierszowy Wynik:

kolumna_dwa = [5 1]

Co wybraliśmy? Wybraliśmy wszystkie te komórki wierszowe w macierzy A, które znajdują się w kolumnie numer 2.

Analogicznie możemy wybrać cały wiersz drugi, stosując zapis:

>> wiersz_dwa = A(2,:) // zwraca wektor wierszowy Wynik:

wiersz_dwa = [4 1 2]

Operator : pobiera wszystkie komórki (kolumny) znajdujące się w wierszu 2

5

Powyższa wersja operatora : jest podstawowa.

Najczęściej stosujemy ogranicznie – wybieramy, które komórki (licząc od 1) chcemy „wyłuskać”. Stosujemy wówczas zapis:

[od]:[ do]

PRZYPISYWANIE FRAGMENTÓW MACIERZY DO INNYCH MACIERZY

• Macierze dwuwymiarowe

Stwórzmy macierz A o wymiarach 5x5 (za pomocą fukcji magic(M)):

>> A = magic(5)

A =

17 24 1 8 15

23 5 7 14 16

4 6 13 20 22

10 12 19 21 3

11 18 25 2 9

Chcemy teraz do tworzonej macierzy B przypisać część macierzy A określonej następująco:

wiersze (licząc od 1): 3-5

kolumny (licząc od 1): 2-4

Przypisujemy odpowiednią część macierzy A do B – stosujemy zapis [od]:[do]

>> B = A(3:5,2:4) // określiśmy macierz zawierającą 3 wiersze i 3 kolumny Wynik:

⎡6 13 20⎤

⎢

⎥

B = ⎢12 19

⎥

21

⎢18 25 2⎥

⎣

⎦

Ogólna idea posługiwania się takim zapisem:

macierzNowa = macierzStara([wier_od]:[wier_do],[kol_od]:[kol_do]) 1. Należy bacznie zwrócić uwagę na to, ile wierszy i kolumn chcemy

„wydobyć” z macierzy wejściowej.

Zapis 30:60 – wcale nie oznacza wydobycie 30 komórek, tylko 31

komórek, ponieważ 60 komórka też się wlicza w zakres.

• Macierze 3- i więcej wymiarowe

Problem jest tu głównie z terminologią. Jeżeli się pojawiają macierze o takich wymiarach, najlepiej jest wyrobić sobie poniższą notację: macierzNowa = macierzStara([od]:[do],[od]:[do],[od]:[do],...) 6

gdzie:

- piersze [od]:[do]

- przedział w pierwszym wymiarze

- drugie [od]:[do]

- przedział w drugim wymiarze

- trzecie [od]:[do]

- przedział w trzecim wymiarze

- itd.

INNE WARIANTY WYBIERANIA KOMÓREK

Sekcja [od]:[do] oznacza wybranie pewnego zakresu komórek i często jest zapisywany w postaci właśnie takiej (np. 2:5), ale istnieją dodatkowe możliwości:

1. istnieje słowo kluczowe end oznaczające element (wiersz bądź kolumnę) końcowy – dzięki temu w pewnych sytuacjach nie musimy znać końcowego numeru kolumny:

>> nowaMacierz = A(4:end,4:end)

/*

wybieramy nową macierz nie znając numerów końcowych kolumn Wynik:

⎡21 3 ⎤

⎢

⎥

⎣2

9⎦

*/

2. Zapis [od]:[do] obowiązują zasady takie jak przy operatorze : - na przykład można podać skok (całkowity) – wówczas możemy określić, które kolumny chcemy wybrać (co drugą, co trzecią itp):

>> nowaMacierz = A(1:2:end,1:2:end)

/*

wybieramy z macierzy A co drugi wiersz i co drugą kolumnę Wynik:

⎡17 1 15 ⎤

⎢

⎥

⎢4 13 22⎥

⎢11 25 9⎥

⎣

⎦

*/

PRZYPISANIE WARTOŚCI ELEMENTOM MACIERZY

Przypisanie takie wykonuje się w prosty sposób:

>> nazwaMac([od]:[do],[od]:[do],..) = <wartość lub jakaś macierz> 7

OBRAZKI

• Przetwarzane obrazki są dla Matlaba macierzami pikseli – o odpowiednich wymiarach, np 300x100, 256x256.

• Obrazy – macierze typu DOUBLE zawierają piksele o wartości 0 lub 1

• Obrazy – macierze typu UINT8 zawierają piksele o 256 odcieniach szarości (0-255).

• W przypadku DOUBLE – wartości poniżej 0 – są zaokrąglane do 0 (obraz czarny); wartości powyżej 1 – zaokrąglane do 1 (obraz biały)

Podstawowa funkcja do pokazywania obrazków:

>> a = [2 3 5 ; 4 5 1]

>> imshow(a, ‘notruesize’)

/* Wyświetlona macierz będzie biała */

Czasami wywołanie samego imshow może nie zadziałać, wówczas stosuje się dodatkowo funkcję figure. (otwiera okno).

>> figure

>> imshow(...)

Funkcja do otwierania obrazka znajdującego się w pliku na dysku:

>> L = imread(‘ścieżka_do_pliku’) // L – macierz obrazu Na przykład:

>> L = imread(‘cameramon.tiff’)

Operacje na obrazku polegają na odpowiednim manipulowaniu tym obrazkiem będącym macierzą odpowiednich liczb.

Przykład:

Mamy na przykład załadowany obrazek 256x256 8bitowy (UINT8).

Chcemy w określonym obszarze zrobić biały obszar. Posługujemy się wówczas komendą przypisania:

>> L = imread(obrazek)

>> L(100:200,50:150) = 255 [lub odpowiednia macierz]

8

ĆWICZENIA:

==========

Na ćwiczeniach trzeba będzie:

1. otworzyć obrazek (np. zdjęcie z dowodu)

>> L = imread(‘ścieżka’);

2. podzielić ten obrazek na dwie równe pionowe części (A i B)

% Wyznaczenie wysokości i szerokości obrazka

>> [wys, szer, gleb] = size(L)

% Połowa długości

>> srodek = int32(szer / 2);

>> srodek1 = srodek + 1; // nie działa, wymagana wcześniejsza konwersja do double. Od wersji 7.0 ta usterka już nie występuje

% Tworzymy macierze połowy obrazka

>> LA = L(1:wys,1:srodek);

>> LB = L(1:wys,srodek1:end);

% Tworzymy macierze odwrócone

>> odwLA = LA(1:end,end:-1:1);

>> odwLB = LB(1:end,end:-1:1);

3. wyświetlić nowy obrazek składający się z części A starego oraz odwróconej części A starego

% Tworzymy odpowiedni obraz – poprzez konkatenację

>> OBRAZ1 = [LA,odwLA];

% Wywołanie figure

>> figure

% Wyświetlenie obrazka

>> imshow(OBRAZ1,’notruesize’);

4. wyświetlić nowy obrazek składający się z obróconej części B oraz normalnej części B starego obrazka

% Konkatenacja

>> OBRAZ2 = [LB,odwLB];

% Wywołanie figure

>> figure

% Wyświetlenie obrazka

>> imshow(OBRAZ2,’notruesize’);

9

Efekty:

Początkowy obrazek:

49 x 166 px (bez ramek)

Obrazek: A i odwrócony A

(większy obraz - wina przeglądarki Matlaba)

Obrazek: obrócony B i B:

10