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