1
AiPO
Wykład 2 – 2007-10-15
1.
Typy obrazów przetwarzanych przez MatLab’a
MatLab w wersji 6.5 obsługuje następujące typy obrazów:
•
Obrazy indeksowane
•
Obrazy ze skalą szarości
•
Obrazy binarne
•
Obrazy RGB
OBRAZY INDEKSOWANE
Obraz indeksowany jest to specjalny typ obrazu, na który składają się dwie połączone ze sobą w specjalny sposób
macierze: pierwsza macierz, zwana macierzą danych, o rozmiarach [m x n], oraz druga – zwana mapą kolorów –
która jest zawsze rozmiarów [m x 3].
Macierz danych (macierz obrazu) jest specjalną macierzą reprezentującą obraz, której szerokosć i wysokość
odpowiada szerokości i wysokości obrazka.
Macierz ta wypełniona jest odpowiednimi liczbami (patrz: typ obrazu a liczby reprezentujące piksele), które
reprezentują każdy piksel i mają za zadanie określić kolor danego piksela poprzez wskazanie numeru wiersza w
specjalnie do tego celu przeznaczonej macierzy – tzw. macierzy kolorów.
Macierz kolorów jest macierzą typu double i ma rozmiar zawsze [m x 3], gdzie m – ilość wierszy tej
macierzy, równa wartości p dla określonego typu obrazu. (p - patrz niżej)
Mapa kolorów przechowuje w każdym swoim wierszu trzy wartości: R, G, B – określające poziom nasycenia
każdej ze składowych – każdy wiersz odpowiada jakimś pikselom w obrazie głównym.
Jaka jest zależność między macierzą danych a mapą kolorów?
Zależność między macierzą danych a macierzą kolorów jest prosta – jeśli piksel o współrzędnych [a, b] ma w
macierzy danych pewną liczbę k, to ta liczba k odpowiada numerowi wiersza w macierzy kolorów – bardzo ważny
jest tu fakt liczenia wierszy w mapie kolorów od 1..
Typ obrazu a liczby reprezentujące piksele
Macierz reprezentująca obraz może być typu:
•
double
•
uint8
•
uint16
Typ danych ma istotny wpływ na to, jakie liczby znajdą się w macierzy danych i ile wierszy zawiera mapa
kolorów:
•
Jeśli macierz danych jest typu double, to liczby są z zakresu [1...p]
// p – maks. dla double
•
Jeśli macierz danych jest typu uint8, to liczby są z zakresu [0...255]
// p = 256
•
Jeśli macierz danych jest typu uint16, to liczby są z zakresu [0...65535]
// p = 65536
2
Przykładowa macierz danych i matryca kolorów: (typ obrazu - double)
⇒
5
5
5
0
0
0
0
0
1
0
1
0
3
4
2
1
Pierwszy piksel ma kolor taki, jaki jest okreslony w pierwszym wierszu mapy kolorów. Piksel o współrzędnych
[1,2] ma kolor zapisany w drugim wierszu, piksel [2,1] w czwartym wierszu a piksel [2,2] w wierszu trzecim.
Czy numerowanie od zera lub jedynki ma jakiś wpływ na analize i przetwarzanie ?
Ma, gdyż numerowanie wierszy w Matlabie zawsze liczy się od jedynki. W przypadku, gdy analizowany jest obraz
typu double, nie ma żadnego problemu, gdyż liczby w macierzy danych wskazujące na numery wierszy w mapie
kolorów są właściwe – tzn. od razu wskazują numer wiersza.
Gorzej nieco jest, gdy analizowany jest obraz typu uint8/uint16. Wwczas w macierzy danych pojawiają się zera, a
widząc zera, Matlab normalnie nie przemapuje danego pola do określonego zerowego wiersza z powodu tego, że
liczy wiersze w macierzy kolorów od jedynki, a nie od zera.
By był w stanie przemapować odpowiednie liczby na numery wierszy, potrzebne jest tzw. przesunięcie. Do każdej
liczby trzeba dodać wartość 1 i otrzymuje się odpowiedni numer wiersza.
Jeśli numer wiersza po dodaniu jedynki przekracza dopuszczalną ilość wierszy w mapie kolorów, to jest on
zaokrąglany do ostaniego wiersza tej mapy.
Przykładowo mamy takie matryce: (typ uint8)
⇒
5
5
5
0
0
0
0
0
1
0
1
0
4
3
2
0
Do piksela [1,1] dodajemy jedynkę i kolor piksela jest określony w pierwszym wierszu.
Do piksela [1,2] dodajemy jedynkę i kolor tego piksela znajduje się w wierszu trzecim
Do piksela [2,1] dodajemy 1 i otrzymujemy czwarty wiersz.
Piksel [2,2] zostanie przemapowany również do czwartego wiersza, mimo, iż dodanie 1 da w wyniku 5.
Warto zauważyć, iż wartości w mapie kolorów w ostatnim (czwartym) wierszu przekraczają dopuszczalną wartość
1. W tym wypadku pikel o numerze wiersza (macierz danych) >=3 będzie miał kolor biały.
Konwersja obrazów -> patrz ostatnie strony
W MatLabie można wyświetlić obrazek indeksowany posługując się poleceniem imshow:
>> imshow(L,cmap); % L – obrazek, cmap – mapa kolorów
Otwarcie obrazka indeksowanego odbywa się poprzez polecenie imready:
>> [L, cmap] = imread(‘obrazek’);
Jeżeli otwierany obraz będzie obrazem w skali szarości, to macierz cmap będzie pusta.
3
OBRAZ W SKALI SZAROŚCI (Intensity image)
Obraz taki o wymiarach [A x B] jest reprezentowany przez macierz o tych samych wymiarach – macierz ta:
•
zawiera wartości w przedziale [0...1], jeżeli obraz jest typu double
•
zawiera wartości w przedziale [0...255], jeżeli obraz jest typu uint8
•
zawiera wartości w przedziale [0...65535], jeżeli obraz jest typu uint16
Warto dodać, iż wartość 0 odpowiada kolorowi czarnemu, wartość 255 (i wyżej) odpowiada kolorowi białemu.
Aby pokazać obrazek, posługujemy się poleceniem:
>> imshow(L,i)
gdzie i – ilość poziomów szarości, np. 32
OBRAZ BINARNY
Obraz binarny o wymiarach [A x B] jest reprezentowany przez macierz o tych samych wymiarach, w której
znajdują się wyłącznie wartości 0 lub 1.
Wartość 0 – kolor czarny, wartość 1 – kolor biały.
Konwersja dowolnego typu na typ binarny:
•
Obraz RGB -> Obraz binarny
>> BW = im2bw(RGB,level)
•
Obraz ze skalą szarości -> Obraz binarny:
>> BW = im2bw(I,level)
•
Obraz indeksowany -> Obraz binarny
>> BW = im2bw(X,MAP,level)
OBRAZ RGB
Obraz RGB o wymiarach [A x B] jest reprezentowany w MatLabie poprzez tablicę trójwymiarową [A x B x 3].
Liczba 3 oznacza, iż przechowywane są informacje określające poziom nasycenia każdego z trzech kolorów (R, G,
B) (stąd tablica 3 wymiarowa) dla każdego piksela oddzielnie.
Ogolnie obraz RGB można przedstawić schematycznie jako odpowiednie połączenie trzech tablic
dwuwymiarowych:
4
Każda z macierzy dwuwymiarowych przechowuje infomacje o nasyceniu danego koloru dla każdego piksela
obrazu. Informacje te to odpowiednie liczby zapisane w jednym z trzech formatów:
•
double – wówczas wartości są określone w przedziale [0...1]
•
uint8 – wówczas wartości są okreslone na przedziale [0...255]
•
uint16 – wówczas wartości są określone na przedziale [0...65535]
Piksel o współrzędnych [m, n] na obrazie typu uint8 ma kolor czerwony. Oznacza to w praktyce, iż:
•
w macierzy składowej R na pozycji [m,n] występuje wartość 255
•
w macierzy składowej G na pozycji [m,n] występuje wartość 0
•
w macierzy składowej B na pozycji [m,n] występuje wartość 0.
Aby prawidłowo wyciąć fragment obrazu w postaci RGB, należy się posłużyć zapisem:
>> F = L(a,b,:); % trzeci argument :
W MatLabie można się „dobrać” do każdej składowej obrazu RGB poprzez odpowiednie wyselekcjonowanie
macierzy z obrazu wejściowego:
>> L = imread(...);
>> skladowaR = L(:,:,1) % macierz R (dwuwymiarowa)
>> skladowaG = L(:,:,2) % macierz G (dwuwymiarowa)
>> skladowaB = L(:,:,3) % macierz B (dwuwymiarowa)
Po ewentualnej modyfikacji macierzy, można je złożyć w trójwymiarze (tworząc obraz) posługując się poleceniem
cat:
>> cat(3,skladowaR,skladowaG,skladowaB)
Zamiana składowych na pozycjach argumentów od 2 do 4 spowoduje zmiane wyświetlanych kolorów.
5
PRZYKŁAD:
Tworzymy obraz składający się z dwóch pikseli: zielonym i szarym (14%)
>> LR = [0 0.14]
>> LG = [1 0.14]
>> LB = [0 0.14]
% Ł
ą
czymy te obrazy w cało
ść
>> LRGB = cat(3,LR,LG,LB);
>> imshow(LRGB,’notruesize’);
PRZYKŁAD:
Chcemy uzyskać tzw. gradient – coś w tym stylu:
>> T = 0:0.01:1;
>> IM = T’ * T;
>> imshow(IM)
PRZYKŁAD:
Chcemy uzyskać takie coś:
>> w = 0:255;
>> q = w’ * w;
% W ML >=7.0 funkcji bitcmp nie zauwa
ż
yłem, wystarczy wtedy: 255-q;
>> q = bitcmp(q,16)
>> q1 = q(1:end,end:-1:1);
>> q2 = [q q1];
>> q3 = q2(end:-1:1,1:end);
>> WYNIK = [q2 ; q3];
>> imshow(WYNIK);
6
PODSTAWOWE FUNKCJE W MATLABIE – konwertujące typy obrazów
•
Konwersja: obraz RGB -> obraz indeksowany
rbg2ind(RGB, n)
Funkcja ta konwertuje obraz RGB (a więc na przykład BMP, JPG, PNG...) do postaci pliku indeksowanego.
Podstawowa wersja komendy wymaga podania parametru n oznaczającego maksymalną wartość p (patrz:
obraz RGB). Dla obrazu UINT8 będzie to 256, dla UINT16 – 65536, dla DOUBLE – 1.
Aby przekonwertować obraz RGB (RGB) do postaci obrazu indeksowanego X z mapą kolorów MAP,
posługujemy się instrukcjami:
>> [X, MAP] = rgb2ind(RGB,n)
•
Konwersja: obraz indeksowany -> obraz RGB
ind2rgb(X, map)
Funkcja ta, odwrotnie do poprzedniej, konwertuje obraz indeksowany do obrazu RGB.
Mając macierz danych X oraz mapę kolorów MAP, można przekonwertować jest do obrazu RGB w sposób
analogiczny do poniższego:
>> RGB = ind2rbg(X,MAP)
Obraz wynikowy jest typu double.
•
Konwersja: obraz indeksowany -> obraz ze skalą szarości
ind2gray(X, map)
Funkcja ta konwertuje obraz indeksowany do obrazu ze skalą szarości.
Jako argumenty podaje się oczywiście macierz danych oraz mapę kolorów.
W wyniku otrzymujemy macierz obrazu w skali szarości – z usuniętymi informacjami nt. odcienia i
nasycenia, ale z informacjami dot. luminancji.
Przykładowa konwersja obrazu RGB do postaci skali szarości może wyglądać następująco: (obraz RGB jest
typu UINT8)
>> I = ind2gray(X, MAP);
Obraz wejściowy (macierz danych) może być typu uint8, uint16 bądź double. Macierz I jest zawsze typu double.
•
Konwersja: obraz ze skalą szarości -> obraz indeksowany
gray2ind(I, n)
Funkcja konwertuje obrazy w skali szarości do obrazów indeksowanych.
W przypadku obrazów binarnych konwersja wygląda następująco:
>> [X, MAP] = gray2ind(I,n)
Parametr n oznacza ilość poziomów szarości. Nie jest obowiązkowy, a nie podanie go oznacza, że ilość poziomów
szarości jest równa 64.
Obraz wejściowy (I) może być typu double, uint8, uint16. Obraz wyjściowy jest albo typu uint8 (jeśli mapa
kolorów ma mniej niż 256 wierszy) albo uint16 (w przeciwnym razie).
7
•
Konwersja: obraz indeksowany -> obraz binarny
im2bw
Funkcja również konwertuje obraz indeksowany do postaci obrazu binarnego:
>> BW = im2bw(X, MAP, level)
Parametr level oznacza próg. Przy konwersji zostają usunięte informacje o odcieniu i nasyceniu, natomiast
pozostają informacje o luminancji pikseli. Piksele, które mają luminancję mniejszą (bądź równą) niż wartość progu,
wówczas są traktowane jako 0 (czarne). W przeciwnym wypadku są białe (1).
•
Konwersja: obraz RGB -> obraz ze skalą szarości
rgb2gray(RGB)
Funkcja konwertuje obraz RGB do obrazu w postaci skali szarości – zostają usunięte informacje nt. odcienia
i nasycenia, pozostają informacje nt. luminancji pikseli.
>> I = rgb2gray(RGB)
•
Konwersja: obraz RGB -> obraz binarny
im2bw(RGB, level)
>> BW = im2bw(RGB,próg)
Tutaj również podajemy wartość progową.
PRZYKŁAD:
Obraz oryginalny RGB:
Obraz binarny – progowanie 0.7:
Obraz binarny – progowanie 0.2:
8
INNE PRZYDATNE FUNKCJE PRZY PRZETWARZANIU OBRAZÓW:
•
max(A)
o
Jeśli argumentem A jest wektor, funckja zwraca jeden element – największy z tego wektora.
o
Jeśli argumentem A jest macierz, funkcja zwraca wektor wierszowy, którego elementami są
największe elementy z poszczególnych kolumn tej macierzy
o
Argumentami funkcji mogą być również dwie macierze – ale równych wymiarów – wówczas
zwracana jest macierz o takich samych wymiarach jak A i B z największymi elementami z dwóch
macierzy podanych jako argument
Przykłady:
>> A = [35 15 ; 45 7 ; 25 59];
>> maxA = max(A);
Wynik:
maxA = [45 59];
>> A = [2 5 ; 7 9 ];
>> B = [3 15 ; 4 8];
>> c = max(A,B)
c =
3 15
7 9
•
min(A)
o
Analogicznie jak wyżej, zwraca elementy minimalne
•
mean(A)
o
Zwraca wartości średnie dla kolumn macierzy podanej jako argument
•
median(A)
o
doczytajcie sobie helpa... :P