Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Octave - szybkie klejenie obrazków cz. 2

Pierwszą część skończyłem pytaniem:

A co będzie, jak obrazki sklejane obok siebie będę różnej wysokości, albo sklejane jeden pod drugim będą różnej szerokości?
A jaka jest odpowiedź? Ano taka, że da się zrobić, ale nie ma to już tak dużego sensu. Trwa to dłużej i trzeba w tym celu przyswoić nieco więcej wiedzy.
Wpis niniejszy traktujcie więc jako gawędę na temat tego co jak w Octave'ie wygląda.

Przyjmijmy, że mamy dwa obrazki: a.png i b.png, pierwszy z nich ma rozmiary 640x480, a drugi 600x400 pikseli.
Wczytajmy je: "a=imread('a.png'); b=imread('b.png');" i sprawdźmy ich rozmiar funkcją size:octave-3.2.4:1> size(a) ans = 480 640 3 octave-3.2.4:2> size(b) ans = 400 600 3 Wynik może odbiegać od oczekiwań. Rozmiary macierzy zawsze podawane są w tej kolejności: najpierw liczba wierszy, potem liczba kolumn. Zawsze!(i jeszcze parę wykrzykników)
W sprawach związanych z wyświetlaniem w komputerze, oś "x" jest pozioma, zorientowana w prawo, a oś "y" pionowa, zorientowana w dół. Kłócą się tu dwie konwencje, stąd ten "rozjazd".
Konwencja macierzowa ma wyższy priorytet choćby z racji wieku.
Dlatego "480 640", zamiast spodziewanych "640 480". A co robi tam jeszcze trójka? Wysokość, szerokość, głębokość? Trójka oznacza trzy warstwy kolorystyczne: pierwsza warstwa, to kolor czerwony, druga to zielony, trzecia - niebieski.
W poprzednim odcinku napisałem, że macierze wzięte z obrazków zawierają liczby z od 0 do 255. Te liczby to oczywiście składowe RGB. Jeden piksel to wektor trzech składowych - wektor brany "wgłąb" z macierzy.
No i jeszcze "ans" trzeba wyjaśnić: jest to zmienna tworzona automagicznie, jej nazwa to skrót od "answer".

Trochę teorii

Zanim pójdziemy dalej, trochę o macierzach i środowisku w ogóle.
W Octave'ie wszystko (no, prawie wszystko) jest macierzą.
Octave jest liberalny, jeśli chodzi o typy danych.
Octave numeruje po ludzku - od 1.
Dlatego możliwe jest takie coś: tworzymy zmienną całkowitoliczbową, przerabiamy ją na wektor liczb (pseudo)rzeczywistych, następnie na macierz dwuwymiarową i w końcu trójwymiarową:octave-3.2.4:2> p=1 p = 1 octave-3.2.4:3> p(3)=1/2 p = 1 0 0.5 octave-3.2.4:4> p(4,4)=0.5 p = 1 0 0.5 0 0 0 0 0 0 0 0 0 0 0 0 0.5 octave-3.2.4:5> p(5,5,3)=0 p = ans(:,:,1) = 1 0 0.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0 0 0 0 0 0 ans(:,:,2) = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ans(:,:,3) = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Jak widać, macierz trójwymiarowa wyświetlana jest warstwami, wygodnie.

Wiedząc to wszystko, możemy przygotować klej, nożyczki i brać się za robotę.

Klejenie

W przypadku klejenia wzdłuż poziomej krawędzi, obrazek wynikowy ma mieć wysokość 880 i szerokość 640 pikseli.
W przypadku klejenia wzdłuż pionowej krawędzi, obrazek wynikowy ma mieć wysokość 480 i szerokość 1240 pikseli.
W obu przypadkach problemem jest drugi obrazek.
Sposobów na to jest kilka.
1. Dolepienie trzeciej macierzy, która uzupełni brakujący kawałek.
2. Rozszerzenie drugiego obrazka o odpowiedni kawałek (to nie to samo, co 1.).
3. Utworzenie macierzy, która będzie pełniła funkcję "podkładu" pod klejone obrazki.

Omówię wszystkie te sposoby.

Trzecia macierz

Wywołanie dla łączenia obok siebie będzie takie:c=[a,[b;d]]a dla łączenia w pionie:c=[a;b,e]gdzie d i e to wypełniacze.
Wypełniacz e, jeśli ma być czarny, będzie macierzą samych zer, o wymiarach 400 na 40 na 3, więc wpisujemy:e=zeros(400,40,3);jeśli biały, to potrzebujemy wszędzie 255:e=255*ones(400,40,3);a jeśli inny kolor (o składowych R, G i B), to trzeba kombinować z notacją dwukropkową:e=R*ones(400,40); e(1:400,1:40,2)=G*ones(400,40); e(1:400,1:40,3)=B*ones(400,40); gdzie "m:n" oznacza "od m do n co jeden".

Rozszerzenie macierzy

Tu sprawa jest prostsza, ale ma to sens tylko dla czarnego paska:b(640,400,1)=0; c=[a;b];

Macierz-tło
Tworzymy macierz z wybranym kolorem, o rozmiarach docelowych (dla uproszczenia biorę czarny):c=zeros(840,640,3);i żeby nie było potem problemów, zmieniamy na siłę jej typ, z "double" na "uint8" (w razie jakichś problemów, których nie przewidziałem, to może pomóc):c=uint8(c);Następnie wklejamy do niej a i b:c(1:480,1:640,:)=a; c(481:880,1:600,:)=b;gdzie ":" oznacza "od początku do końca" i jest równoważne "1:end".

Pozostaje zapisać.

Na koniec dwie ciekawostki:
1. są obrazki, które dają macierz o trzecim wymiarze równym 4 - kto wie czemu, ręka do góry ;)
2. pewne formaty graficzne można importować do innej postaci: macierz dwuwymiarowa z numerami kolorów + mapa z kolorami.
Tematem obrazków jeszcze Was z raz pomęczę. 

oprogramowanie porady programowanie

Komentarze

0 nowych
Saskatchewan   7 #1 19.11.2011 10:05

Może czwarty wymiar, to kanał alfa, czyli stopień przezroczystości?

matmatyk   1 #2 19.11.2011 18:33

Lub obrazki, w których kolory są zapisane w formacie CMYK (używany w poligrafii).

  #3 20.11.2011 05:45

Jako edytor z graficznym UI polecam http://sourceforge.net/projects/qocterm/

Jaahquubel_   12 #4 21.11.2011 11:56

Saskatchewan ma rację, tyle że to nie czwarty wymiar, a czwarta "warstwa" w wymiarze trzecim. Sytuację taką spotkałem w przypadku loga DobrychProgramów, które jest w formacie PNG.
Dodam też, że da się wczytywać GIF-y jako mapę kolorów (rozmiary długość mapy x 3 składowe) + macierz dwuwymiarową z numerami kolorów z mapy.

@Anonim
Oparte o Qt, a jest tylko na Win. Nie ma zrzutów do obejrzenia. Dawno nie było aktualizacji.
Nie zachwycił mnie ten program.

Jaahquubel_   12 #5 23.11.2011 08:27

@RaveStar
Mógłby zrobić choćby na jedną, np. tę jedynie słuszną. Poza tym, "skompiluj sobie" to nie jest najlepszy sposób na zachęcenie mnie do instalacji czegoś, czego nie potrzebuję. :P

  #6 11.07.2012 19:17

Jak skleić macierz A z jej lustrzanym odbiciem ?

Jaahquubel_   12 #7 12.07.2012 10:49

[a;flipdim(a,1)] albo [a,flipdim(a,2)], zależnie od tego w którą stronę sklejasz i odbijasz.