Blog (76)
Komentarze (1.5k)
Recenzje (3)
@Jaahquubel_Octave - szybkie klejenie obrazków cz. 1

Octave - szybkie klejenie obrazków cz. 1

16.11.2011 17:50, aktualizacja: 11.12.2011 00:41

Wstęp

Z racji istniejącego jeszcze na DobrychProgramach ograniczenia na liczbę obrazków w jednym wpisie na blogu, kilkukrotnie już musiałem sklejać kilka obrazków w jeden. Ostatnim razem było to aż 5 obrazków. Na szczęście nie musiałem stosować brutalnej metody, która przychodzi do głowy jako pierwsza: otworzyć w GIMP-ie pierwszy obrazek, rozciągnąć płótno, dodać drugi obrazek i tak do skutku. Szybko i sprawnie zrobiłem to w Octave'ie.

GNU Octave to jedno z moich podstawowych narzędzi pracy, obok Opery, Kile i Geany. Jest to wolny pakiet numeryczny, podobnie jak opisany przez arlida Scilab. To, co arlid dotąd napisał o obsłudze Scilaba (cz. 1 i cz. 2 ), przekłada się w całości na Octave'a.

Do dzieła

Przyjmijmy na wstępie, że mamy do sklejenia dwa obrazki o takiej samej szerokości i wysokości (np. zrzuty z okna jakiegoś kreatora). Przyjmijmy też, że pierwszy obrazek nazwaliśmy "a.png", a drugi "b.png" (nazwy im krótsze, tym wygodniej). Po uruchomieniu Octave'a, należy oczywiście przejść do katalogu, w którym znajdują się owe obrazki, u mnie jest to Pulpit, a więc:

octave-3.2.4:1> cd ~/Pulpit

Teraz wczytujemy pliki do zmiennych (znów, nazwy im krótsze, tym wygodniej):

octave-3.2.4:2> a=imread('a.png');
octave-3.2.4:3> b=imread('b.png');

Uwaga! Średniki na końcach linii są istotne - bez nich wyświetli się cała zawartość podanych zmiennych. Zmienne te są macierzami (tu: trójwymiarowymi tablicami liczb od 0 do 255) i to te macierze zostaną wypisane (nie zostaną wyświetlone obrazki). Teraz można przejść do klejenia. Utworzymy dwie nowe zmienne (c i d), w których znajdą się sklejone obrazki. Zmienna c będzie macierzą o wysokości równej sumie wysokości macierzy a i b, bo skleimy w niej a.png nad b.png. Zmienna d będzie macierzą o szerokości równej sumie szerokości macierzy a i b, bo skleimy w niej a.png na lewo od b.png.

octave-3.2.4:4> c=[a;b];
octave-3.2.4:5> d=[a b];

Tu znów musimy pamiętać o średnikach na końcach, aby uniknąć zasypania ekranu mnóstwem liczb. Bardziej istotne jest jednak to, co dzieje się między znakiem równości a średnikiem: "[" oznacza początek wprowadzania macierzy, "]" oznacza koniec wprowadzania macierzy, do macierzy c i do macierzy d wstawiamy wszystkie elementy macierzy a i b (całe obrazki), więc wystarczy podanie nazw zmiennych a i b, średnik rozdzielający a i b w pierwszym klejeniu oznacza koniec wiersza macierzy, czyli że b idzie pod a, czyli to, o co nam chodziło, spacja rozdzielająca a i b w drugim klejeniu oznacza następny element w wierszu, czyli że b jest obok a, czyli znów to, jak miało być. Zamiast spacji może być też przecinek - bez różnicy.

Efekt możemy podejrzeć:

octave-3.2.4:6> imshow(c)
octave-3.2.4:7> imshow(d)

Tutaj średnik na końcu jest nieistotny.

Jeśli mamy więcej obrazków, postępujemy podobnie:

c=[a1;a2;a3;a4];

w przypadku kolumny obrazków i

c=[a1 a2 a3 a4];

w przypadku poziomego ciągu. Można też połączyć obie sprawy: a1 i a2 obok siebie u góry, a3 i a4 pod nimi, też obok siebie:

c=[a1 a2;a3 a4];

Przyszedł czas na zapis:

octave-3.2.4:8> imwrite(c,'c.png')

Macierz c zapisujemy do pliku c.png. Octave po rozszerzeniu domyśla się jak ma tę macierz wykorzystać, więc żadne inne opcje nie są konieczne (choć istnieją).

Całą operację można jeszcze zapisać skrótowo w jednej linii:

imwrite([imread('a.png');imread('b.png')],'c.png')

oraz uprościć jeszcze bardziej, wywołując Octave'a z wiersza poleceń z podaną wyżej komendą jako parametrem:

q@q-laptop:~$ octave-3.2.4 -q --eval 'cd ~/Pulpit/; imwrite([imread("a.png");imread("b.png")],"c.png")'

"octave-3.2.4" - tym poleceniem odpalam u siebie Octave'a, polecenie to zależy od systemu operacyjnego, "‑q" jest tu po to, żeby Octave nie zanudzał nas informacjami powitalnymi, "-‑eval" mówi, że jest kod do wykonania (więcej parametrów nie ma, więc po wykonaniu kodu, Octave się zamknie), średnik w kodzie separuj poszczególne polecenia (tu mógłby też być przecinek). W samym kodzie zmieniłem cudzysłowy pojedyncze na podwójne - Octave'owi nie robi różnicy który cudzysłów dostanie, ale że całe polecenie ubrane jest w cudzysłów, bez tej zmiany by się pogryzło.

Komplikator

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? O tym w części drugiej.

PS. Inspiracją do takiego wykorzystania Octave'a był wpis Saskatchewana na jego blogu w My Opera.

Wybrane dla Ciebie
Komentarze (9)