Práca s maticami a vektormi III
Práca s vektormi a maticami v MATLAB je natoľko zásadný tému, že je rozdelené do troch lekcií. Informácie v jednotlivých častiach sa prekrývajú a zakaždým sú podané trochu iným spôsobom. Umožní tak nahliadnuť na problematiku z rôznych uhlov.
V prvej časti sme si vysvetlili indexovanie a prácu s bunkami. Druhá časť sa dopodrobna zaoberá tvorbou vektorov, prístupom k jednotlivým prvkom a ich filtrovanie. Podobné témy sa preberajú aj v tejto časti, len s pomocou matíc (dvojrozmerné polia) a na praktické ukážke úpravy fotografie.
Tvorba matíc
K jednoduché tvorbe matíc sa používajú, rovnako ako u vektorov, hranaté
zátvorky. Oddeľovačom prvkov je medzera alebo čiarka, oddeľovačom riadkov
je bodkočiarka. Ak teda chceme maticu s prvkami od 1 do
25, kde budú hodnoty naskladané v stĺpcoch, môžeme ju
zapísať takto:
A = [1,6,11,16,21;2,7,12,17,22;3,8,13,18,23;4,9,14,19,26;5,10,15,20,25]
A alebo pomocou funkcie reshape(), ktorá zmení tvar (odtiaľ
názov) vektora od 1 do 25, tak aby v prvej i druhej
dimenzii bolo 5 prvkov:
A = reshape(1:25,5,5);
reshape() je funkcia, ktorú je vhodné mať v povedomí.
Občasné "reshapnutí" dokáže častokrát kód zjednodušiť.

Čo znamenajú ryšavá čísla s modrými šípkami je predmetom nasledujúcej kapitoly.
Indexovanie matíc
Matica sa v MATLABe dajú indexovať dvojakým spôsobom. Ak chceme pristúpiť k prvku na prvom riadku piateho stĺpca, bude to prekvapivá takto:
prvek_1_5 = A(1,5); %21
Riadky aj stĺpce sa indexujú od jednotky az ľavého horného rohu (rovnako ako bežná tabuľka, napríklad v Exceli). Okrem tohto dvoučíselného náberu môžeme využiť iba jednu hodnotu:
devaty_prvek = A(9); %9
_ Týmto zápisom hovoríme - vezmi prvok, ktorý je na deviatej pozícii. MATLAB pozíciu počíta zas z ľavého horného rohu po stĺpcoch. Názorne je to vysvetlené na obrázku vyššie. Výhoda takého zápisu je, že jedno číslo je jednoduchšie pre uchovanie a počítanie. Dajú sa tak pochopiteľne indexovať aj viacrozmerné objekty.
Výrezy matíc
Okrem jednotlivých čísel je možné vyberať aj "podmatice", teda výrez pôvodné matice. Je to len kombinácia znalostí, ktoré sú vysvetlené v predchádzajúcom článku (tvorba a indexovanie vektorov).

Premenná vyrez = A(1:3,1:2) obsahuje všetky riadky jedna až
tri v prvom a druhom odstavci. Ekvivalentným zápisom by bolo
vyrez = A([1 2 3],[1 2]). Existuje pár vychytávok, ako si také
vyrezávanie zjednodušiť. Jednou z nich je dvojbodka a druhou kľúčové
slovo end. Dvojbodka hovorí "všetky" a end je
odkazom na posledný prvok. Tým pádom dvojbodka je rovnaká ako
1:end. Pre ukážku si tu uveďme niekoľko spôsobov, ako vybrať
štvrtý stĺpec z matice o veľkosti 5x5:
A(1:end, 4) %Od prvního řádku do posledního A(:,4) %Dvojtečka znamená "všechny" (řádky) A(1:1:5, 4) %Řádky od 1 po 1 do 5 A(1:5,4) %Řádky od 1 do 5 (prostřední 1 tam být nemusí) A([1, 2, 3, 4, 5], 4) %Řádky 1,2,3,4,5 A([1 2 3 4 5], 4) %V definici [vektoru] je mezera ekv. čárce
Najlepší spôsob je (takmer vždy) ten najkratší, teda výber štvrtého
stĺpca pomocou príkazu: A(:,4). Navyše je tento zápis
všeobecný pre akúkoľvek maticu, ktorá má aspoň 4 stĺpce.
Úprava matíc
Ak chceme zmeniť hodnotu v matici, musíme povedať kde a na čo. Pred znakom rovnosti bude kde, za znakom rovnosti čo. Nuly do štvrtého stĺpčeku priradíme nasledovne:
A_nuly_ve_4sl = A ;%kopie matice A, abychom si ji nepřepsali. A_nuly_ve_4sl(:, 4) = 0;
Tri hornej riadky nahradíme jednotkou pomocou:
A_prvni3radky = A; A_prvni3radky(1:3, :) = 1;
Posledný stĺpec nakopírujeme do posledného riadka:
A_posledni_rad_sl = A; A_posledni_rad_sl(end, :) = A_posledni_rad_sl(:,end);
Nakoniec ztrojnásobíme každý druhý prvok matice:
A_3x = A; A_3x(1:2:end) = A_3x(1:2:end)*2;
Teraz máme vedomosti o vytváranie, indexovanie a úprave matíc. Tieto znalosti využijeme v nasledujúcej kapitole k úprave jasu fotografie - taký Photoshop od podlahy.
Cvičenie - úprava fotografie
Digitálna fotografia je súbor pixelov v mriežke - teda matice. Čiernobiela fotografia je iba jedna matica, kde hodnoty prvkov určujú ako bude daný pixel svetlý. Jedna taká fotografie je súčasťou každej verzie MATLABe a načítate ju a zobrazíte takto:
I = imread('cameraman.tif');
imshow(I)
Jedná sa o nasledujúce fotografiu kameramana:

Terajším úlohou bude nasledujúce:
Zmeňte všetky pixely, ktoré sú nižšie ako priemer, na bielu farbu.
Priemer hodnôt pixelov
K vypočítanie priemeru existuje nepríliš zložito nazvaná funkcia
mean(). Parametrom all oznamujeme, že to chceme
spočítať cez všetky prvky (inak by sme počítali priemer v každom
riadku).
prumer = mean(I, 'all');
Výsledkom je hodnota 117.7245, čo je v blízkosti polovice
šedotónového rozsahu (0 - 255).
Výber pixelov vyšších ako priemer
Nemusíme tu využívať dvojitý cyklus na prejdenie dvojrozmerného poľa. Stačí jeden riadok kódu:
kde_vice_nez_prumer = I < prumer;
Výsledkom bude binárne matice o rovnakej veľkosti ako je obrázok. Prvky pole, ktoré spĺňajú podmienku, sa stanú jednotkou, ostatné nulou.
Biela farba
Ako už som spomenul vyššie, šedotónový obraz sa pohybuje v rozsahu od
0 - 255. Dôvod je prostý - na jeden pixel treba
jeden bajt pamäte. V jenom bajtu je 8 bitov, 8 2 = 256. Najtmavší
farba, teda čierna (čiže absencia svetla) je definovaná nulou.
Najsvetlejšie farba, teda biela, 255. Potrebujeme teda na všetky
miesta, ktoré spĺňajú podmienku, nastaviť 255.
Zmena farieb vybraných pixelov
Binárne matice kde_vice_nez_prumer môže slúžiť tiež na
indexovanie, teda "náberu" daných prvkov, s ktorými chceme niečo robiť:
I2 = I;%nakopirovani matice
I2(kde_vice_nez_prumer) = 255;
Zobrazenie výsledku
Výsledok zobrazíme takto:
imshow(I2)
Čo vyústi v nasledujúci obrázok:

Záver
Celý MATLAB je založený na maticiach (má to aj v názve). Pochopenie toho, ako sa tu s nimi správne nakladá, je užitočná znalosť nielen pre spracovanie obrazu.
Druhá úloha
Riešenie nasledujúce úlohy nájdete na konci priloženého súboru (obsahuje tiež všetok kód z článku). Polovicu obrázku kameramana zmeňte na šedú farbu:

Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 14x (1.45 kB)
Aplikácia je vrátane zdrojových kódov

