Ćwiczenie P-3. Processing - przetwarzanie obrazów 2D i renderowanie scen 3D. Grafika komputerowa. Instrukcja laboratoryjna



Podobne dokumenty
Processing. Podstawy Processingu

Podstawy Processingu. Diana Domańska. Uniwersytet Śląski

Grafika 3D program POV-Ray - 1 -

2 Przygotował: mgr inż. Maciej Lasota

Ćwiczenie 1 Automatyczna animacja ruchu

Ustawienia materiałów i tekstur w programie KD Max. MTPARTNER S.C.

Rysunek 1: Okno timeline wykorzystywane do tworzenia animacji.

ANALIZA I INDEKSOWANIE MULTIMEDIÓW (AIM)

GIMP. Ćwiczenie nr 6 efekty i filtry. Instrukcja. dla Gimnazjum 36 - Ryszard Rogacz Strona 18

1.3. Tworzenie obiektów 3D. Rysunek 1.2. Dostępne opcje podręcznego menu dla zaznaczonego obiektu

Grafika Komputerowa Materiały Laboratoryjne

WSTĘP; NARZĘDZIA DO RYSOWANIA

Dodawanie grafiki i obiektów

Ćwiczenie 4 - Podstawy materiałów i tekstur. Renderowanie obrazu i animacji

Baltie 3. Podręcznik do nauki programowania dla klas I III gimnazjum. Tadeusz Sołtys, Bohumír Soukup

Implementacja filtru Canny ego

narzędzie Linia. 2. W polu koloru kliknij kolor, którego chcesz użyć. 3. Aby coś narysować, przeciągnij wskaźnikiem w obszarze rysowania.

Obsługa programu Paint materiały szkoleniowe

Wprowadzenie do rysowania w 3D. Praca w środowisku 3D

Obsługa programu Paint. mgr Katarzyna Paliwoda

1. Opis okna podstawowego programu TPrezenter.

Microsoft Small Basic

Ćwiczenie 2 Warstwy i kształty podstawowe

1. Umieść kursor w miejscu, w którym ma być wprowadzony ozdobny napis. 2. Na karcie Wstawianie w grupie Tekst kliknij przycisk WordArt.

Maskowanie i selekcja

Animacje cz. 2. Rysujemy koło zębate

TECHNIKI MULTIMEDIALNE LABORATORIUM GIMP: Projektowanie tła

WSTAWIANIE GRAFIKI DO DOKUMENTU TEKSTOWEGO

// Potrzebne do memset oraz memcpy, czyli kopiowania bloków

Rysowanie punktów na powierzchni graficznej

Oświetlenie. Modelowanie oświetlenia sceny 3D. Algorytmy cieniowania.

Jak dodać własny szablon ramki w programie dibudka i dilustro

Jak zrobić klasyczny button na stronę www? (tutorial) w programie GIMP

0. OpenGL ma układ współrzędnych taki, że oś y jest skierowana (względem monitora) a) w dół b) w górę c) w lewo d) w prawo e) w kierunku do

Spis treści. Adobe Photoshop lab. 2 Jacek Wiślicki,

WASM AppInventor Lab 3. Rysowanie i animacja po kanwie PODSTAWY PRACY Z KANWAMI

Użycie przestrzeni papieru i odnośników - ćwiczenie

Wstęp do GIMP wycinanie obiektu z obrazka, projekt napisu. Rozpoczynamy prace w GIMP-e

NARZĘDZIA DO ZAZNACZANIA

Edytor tekstu OpenOffice Writer Podstawy

IRONCAD. TriBall IRONCAD Narzędzie pozycjonujące

DARMOWA PRZEGLĄDARKA MODELI IFC

Zadanie 1. Ściana. 1. Potrzebne zmienne w dołączonym do zadania kodzie źródłowym

Ćwiczenie nr 2 - Rysowanie precyzyjne

Obsługa grafiki w Delphi, rysowanie na płótnie, obsługa myszki, zapisywanie obrazków do plików, bitmapy pozaekranowe.

GIMP Grafika rastrowa (Ćwiczenia cz. 2)

Animowana grafika 3D. Opracowanie: J. Kęsik.

POMOC / INSTRUKCJA OBSŁUGI

AutoCAD LT praca na obiektach rastrowych i nakładanie barw z palety RGB na rysunki.

Wstawianie nowej strony

Ćwiczenia z grafiki komputerowej 4 PRACA NA WARSTWACH. Miłosz Michalski. Institute of Physics Nicolaus Copernicus University.

Ćw. I Projektowanie opakowań transportowych cz. 1 Ćwiczenia z Corel DRAW

Druga aplikacja Prymitywy, alpha blending, obracanie bitmap oraz mały zestaw przydatnych funkcji wyświetlających własnej roboty.

Grafika Komputerowa Wykład 5. Potok Renderowania Oświetlenie. mgr inż. Michał Chwesiuk 1/38

KGGiBM GRAFIKA INŻYNIERSKA Rok III, sem. VI, sem IV SN WILiŚ Rok akademicki 2011/2012

Rysowanie precyzyjne. Polecenie:

1 Wstęp teoretyczny. Temat: Manipulowanie przestrzenią. Grafika komputerowa 3D. Instrukcja laboratoryjna Układ współrzędnych

LABORATORIUM 7 Cel: 1_1

PyGame Gra w Ponga. Spis treści

Oświetlenie obiektów 3D

Photoshop Podstawy obsługi

Wypełnianie kolorem lub deseniem

Fotografia cyfrowa obsługa programu GIMP. Cz. 18. Tworzenie ramki do zdjęcia. materiały dla osób prowadzących zajęcia komputerowe w bibliotekach

3.7. Wykresy czyli popatrzmy na statystyki

KATEDRA MECHANIKI I PODSTAW KONSTRUKCJI MASZYN. Instrukcja do ćwiczeń laboratoryjnych z elementów analizy obrazów

Grafika komputerowa. Zajęcia 7

Adobe Photoshop Dodatek do lab4 J.Wiślicki, A.Romanowski;

OpenGL Światło (cieniowanie)

Pokażę w jaki sposób można zrobić prostą grafikę programem GIMP. 1. Uruchom aplikację GIMP klikając w ikonę na pulpicie.

54. Układy współrzędnych

Advance CAD 2016 SP2. W tym dokumencie opisano ulepszenia w Advance CAD Service Pack 2. Co nowego w Advance CAD 2016 SP2

Grafika rastrowa (bitmapa)-

Tworzenie prezentacji w MS PowerPoint

I Tworzenie prezentacji za pomocą szablonu w programie Power-Point. 1. Wybieramy z górnego menu polecenie Nowy a następnie Utwórz z szablonu

Jak uzyskać efekt 3D na zdjęciach z wykorzystaniem programu InkScape

Grafika komputerowa. Zajęcia IX

Studia Podyplomowe Grafika Komputerowa i Techniki Multimedialne, 2017, semestr II Modelowanie 3D - Podstawy druku 3D. Ćwiczenie nr 4.

Grafika komputerowa. Dla DSI II

Opis Edytora postaci Logomocji

Obsługa mapy przy użyciu narzędzi nawigacji

CorelDRAW. 1. Rysunek rastrowy a wektorowy. 2. Opis okna programu

CorelDRAW. wprowadzenie

Diagnostyka obrazowa

Interakcje wizualno-muzyczne. Processing. w programowaniu obrazu. Piotr Welk

Spis treści. Programowanie w ImageJ. Zadanie 1. Zadanie 2

Animacje z zastosowaniem suwaka i przycisku

Allegro5 3/x. Przykład wklejamy go do dev'a zamiast kodu domyślnego dal programu z allegro i kompilujemy.

Projektowanie graficzne. Wykład 2. Open Office Draw

Unity 3D - własny ekran startowy i menu gry

Grafika Komputerowa. Zajęcia X

Fragment tekstu zakończony twardym enterem, traktowany przez edytor tekstu jako jedna nierozerwalna całość.

Multimedia i interfejsy. Ćwiczenie 5 HTML5

Instrukcja obsługi funkcji specjalnych szablonu C01 v.1.0

Tabele. Przykład 15a.htm. <HTML><HEAD><TITLE> Cennik</TITLE></HEAD><BODY><H3>Cennik</H3> <TABLE BORDER="1"> <TR>

Rozdział 1. Wstęp 5. Rozdział 2. Pierwsze kroki 13. Rozdział 3. Podstawy rysunku wektorowego 35

Ćwiczenie 3: Rysowanie obiektów w programie AutoCAD 2010

Rzutowanie DOROTA SMORAWA

Następnie zdefiniujemy utworzony szkic jako blok, wybieramy zatem jak poniżej

Compas 2026 Vision Instrukcja obsługi do wersji 1.07

Grafika w aplikacjach lp. Jak zmienić kolor tła?

Transkrypt:

Ćwiczenie P-3 Processing - przetwarzanie obrazów 2D i renderowanie scen 3D Instrukcja laboratoryjna opracował: mgr inż. Jakub Możaryn Człowiek - najlepsza inwestycja Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego Warszawa 2009

2 Ćwiczenie P-3 SPIS TREŚCI 1. Operacje na plikach graficznych... 3 1.1. WYŚWIETLANIE PLIKÓW GRAFICZNYCH - KLASA PImage... 3 1.1.1. Dopasowanie okna do rozmiaru obrazu... 3 1.1.2. Modyfikacja nasycenia i przezroczystości obrazu... 4 1.2. OBRÓBKA OBRAZU OPERACJE NA PIKSELACH... 5 1.2.1. Dostęp do pikseli i modyfikacje koloru... 7 1.2.2. Interaktywne przetwarzanie obrazu... 7 2. Oświetlenie... 11 2.1. ŚWIATŁO OTACZAJĄCE... 11 2.2. ŚWIATŁO KIERUNKOWE... 11 2.3. ŚWIATŁO PUNKTOWE... 11 2.4. ŚWIATŁO SKONCENTROWANE... 12 2.5. DODATKOWE FUNKCJE ZWIĄZANE Z OŚWIETLENIEM... 12 2.6. OŚWIETLANIE SCENY... 13 3. Nakładanie tekstury... 15 3.1. INFORMACJE PODSTAWOWE... 15 3.2. NAKŁADANIE TEKSTURY NA ZŁOŻONY KSZTAŁT... 16 4. Kamera... 18 5. Zadania do samodzielnego wykonania... 19 5.1. ZADANIE INTERAKTYWNE PRZETWARZANIE OBRAZU, c.d.... 19 5.2. ZADANIE NAKŁADANIE TEKSTURY NA RUCHOME OBIEKTY... 20 6. Literatura... 20

Ćwiczenie P-3 3 1. Operacje na plikach graficznych 1.1. WYŚWIETLANIE PLIKÓW GRAFICZNYCH - KLASA PImage W Procesingu uproszczono pracę z plikami graficznymi, udostępniając klasę PImage. Obiekty tej klasy przechowują informacje o plikach graficznych. Klasa PImage obsługuje popularne formaty, t.j. GIF, JPEG, TGA i PNG. Wyświetlanie pliku graficznego z wykorzystaniem klasy PImage jest stosunkowo proste. Na początku należy dodać plik graficzny do tworzonego projektu. W tym celu wybiera się z menu głównego opcje Sketch >Add File. Pozwala to na dodanie pliku danych do projektu (nie zawsze musi być to plik graficzny, dotyczy to generalnie plików z danymi). Innym sposobem jest wyświetlenie folderu z plikami dodanymi do projektu Sketch > Show Sketch Folder i przekopiowanie pliku graficznego do katalogu /data. 1.1.1. Dopasowanie okna do rozmiaru obrazu Pierwsza przykładowa aplikacja będzie wyświetlała obraz i dopasowywała okno do jego rozmiaru. Na początku zostanie zadeklarowany obiekt klasy PImage. Aplikacja 1.1 deklaracja zmiennych // Deklaracja obiektu klasy PImage PImage img; Następnie, w funkcji inicjującej, obiekt klasy PImage musi zostać skojarzony z wybranym plikiem graficznym z katalogu /data. W tym celu należy skorzystać z funkcji loadimage(), która wywoływana jest z parametrem będącym nazwą pliku. Img=loadImage(string nazwapliku) Rozmiar obrazka można odczytać, korzystając z własności width (szerokość) i height (wysokość) obiektu klasy PImage. Aplikacja 1.1 funkcja inicjująca void setup() { //przypisanie obiektowi img odpowiedniego pliku graficznego img = loadimage("lilie wodne.jpg"); //dopasowanie rozmiaru okna do rozmiaru obrazu size(img.width,img.height); W ostatnim etapie zostaje do napisania funkcja rysująca. Jest w niej wykorzystana funkcja image(img,0,0), która rysuje obraz w oknie. image(pimage img, int/float WspX, int/float WspY) Parametry WspX, WspY określają współrzędne lewego górnego rogu obrazu oraz położenie obrazu na ekranie.

4 Ćwiczenie P-3 Aplikacja 1.1 funkcja rysująca void draw() { background(0); //wyświetlenie obrazu zapisanego w obiekcie img image(img,0,0); Inną przydatną funkcją zaimplementowaną w Processingu jest CreateImage(), pozwalająca na utworzenie nowego, pustego obrazu. img=createimage(int/float szer, int/float wys, format) Funkcja CreateImage()wywoływana jest z trzema parametrami: szerokość, wysokość określającymi rozmiar tworzonego obrazu, oraz informacją o formacie format. Zmienna format może przyjmować wartości RGB, ARGB (RGB z kanałem alpha), ALPHA (skala szarości z kanałem alpha). 1.1.2. Modyfikacja nasycenia i przezroczystości obrazu Kolejny przykład będzie dotyczył obsługi parametru nasycenia obrazu i parametru alpha (przezroczystość). W aplikacji zostaną nałożone na siebie dwa rożne obrazy. Nasycenie i przezroczystość jednego z obrazów będą zmieniały się w zależności od położenia kursora względem okna aplikacji. W ten sposób uzyskany zostanie efekt przenikania dwóch obrazów. Na początku zostaną zadeklarowane dwa obiekty klasy PImage. Następnie w funkcji inicjującej jeden z obrazów zostanie potraktowany jako tło, natomiast drugi zostanie wyświetlony jako obraz. Funkcja rysująca pozostaje pusta - nie będą się w niej znajdowały instrukcje. Aplikacja 1.2 deklaracja zmiennych, funkcja inicjująca, funkcja rysująca PImage img1, img2; void setup() { img1 = loadimage("lilie wodne.jpg"); img2 = loadimage("niebieskie góry.jpg"); size(img1.width,img1.height); background(img1); image(img2,0,0); } void draw() {} //tło //obraz //pusta funkcja rysująca Pozostaje do obsłużenia ruch myszy (funkcja mousemoved()). Do zmiany parametru nasycenia obrazu img2, oraz parametru odpowiadającego za przezroczystość zostanie wykorzystana funkcja tint(). Funkcja ta określa sposób wyświetlania pikseli na ekranie. Wywoływana może być z różną liczbą parametrów (jeden przezroczystość; dwa nasycenie i przezroczystość; pięć wartości kanałów RGB, nasycenie i przezroczystość ). tint(int/float argr, int/float argg, int/float argb, int/float intens, int/float alpha); W tworzonej aplikacji przezroczystość i nasycenie zależy od położenia kursora wobec okna z programem. Współrzędna X położenia kursora wpływa na wartość parametru intensywności obrazu img2, natomiast współrzędna Y położenia kursora wpływa na wartość parametru przezroczystości obrazu img2.

Ćwiczenie P-3 5 Aplikacja 1.2 obsługa zdarzenia związanego z ruchem kursora void mousemoved(){ background(img1); tint(round(mousex*255/width), round(mousey*255/height)); image(img2,0,0); Rysunek 1.1. Okno aplikacji 1.2, przenikanie dwóch rysunków 1.2. OBRÓBKA OBRAZU OPERACJE NA PIKSELACH W przypadku kiedy w programie wymagany jest dostęp do poszczególnych pikseli obrazka, należy skorzystać z dwóch funkcji, loadpixels() i updatepixels(). Funkcja loadpixels(), wywołana dla danego obrazka, zapisuje informację o kolorze poszczególnych pikseli do wektora o nazwie pixels[]. Można się odwołać do pikseli ekranu (tła) lub do pikseli obiektu będącego obrazkiem. Ekran (tło) pixels[1]=c; Obrazek img.pixels[1]=c; W Processingu położenie każdego piksela jest podawane jako liczba całkowita, obliczana wg. następującej zależności. położenie=x + szerokość_okna*y; (1) Przykładowo dostęp do piksela [10, 10] na oknie o szerokości 200, jest następujący pixels[x+200*y]=c; Po zakończeniu pracy z pikselami należy wywołać funkcję updatepixels(). Tylko wtedy zmiany zostaną zapisane. Operacje na poszczególnych pikselach wymagają modyfikacji różnych parametrów m.in. składowych barw RGB, przezroczystości, intensywności. W języku Processing umożli-

6 Ćwiczenie P-3 wiono zaawansowaną obsługę własności poszczególnych pikseli i określenie ich koloru, udostępniając typ danych o nazwie color, który przechowuje wartości związane z określonym kolorem. Każdy element wektora pixels[] jest zmienną typu color. Kolory mogą być ustawione z wykorzystaniem funkcji get(), color(), lub określone w postaci heksadecymalnej np. #FFCC00 lub 0xFFFFCCOO. Przydatne funkcje związane z określaniem koloru zostały zebrane w tabeli 1.1. W tabeli 1.1 opisano funkcję get(), która oprócz odczytania wartości koloru wybranego piksela pozwala na wybranie całego fragmentu obrazu. W przypadku odczytywania koloru piksela należy podać jego współrzędne. Jeśli wybierany jest fragment obrazu należy podać współrzędne jego górnego lewego rogu, oraz szerokość i wysokość. Odczytanie koloru piksela color cp; cp=get(10,10); Wybór fragmentu obrazu PImage img; img=get(10,10,300,300); Tabela 1.1. Funkcje związane z określeniem i modyfikacją koloru Funkcja hex(color c); red(color); green(color c); blue(color c); hue(color c); saturation(color c); brightness(color c); get(); color c=color(); colormode(); Opis Konwertuje wartość typu byte, char, int, color na łańcuch znaków w notacji heksadecymalnej. Odczytanie rzeczywistych wartości składowych RGB ze zmiennej typu color podawanej jako parametr Odczytuje rzeczywistą wartość odcienia ze zmiennej typu color podawanej jako parametr. Odczytuje rzeczywistą wartość nasycenia ze zmiennej typu color podawanej jako parametr. Odczytuje rzeczywistą wartość jasności ze zmiennej typu color podawanej jako parametr. Odczytuje kolor danego piksela, w tym wypadku zwraca zmienną typu color. Parametrami są wartości x i y położenia piksela na obrazie. Generuje kolor zwracając zmienną typu color. Parametry interpretowane są jako wartości kanałów RGB lub HSB, w zależności od ustawionego trybu wyświetlania kolorów. Ustawienie trybu wyświetlania kolorów.

Ćwiczenie P-3 7 1.2.1. Dostęp do pikseli i modyfikacje koloru Sposób dostępu do poszczególnych pikseli obrazu i modyfikacji ich własności zostanie pokazany na przykładzie aplikacji służącej do prostej obróbki obrazu. Na początku zostanie zadeklarowany obiekt klasy PImage. W funkcji inicjującej zostanie przypisany mu odpowiedni rysunek, do którego dopasowane zostanie okno programu. Aplikacja 1.3. deklaracja zmiennych i funkcja inicjująca PImage img; void setup() { img = loadimage( "Lilie wodne.jpg"); size(img.width,img.height); noloop(); Funkcja rysująca będzie wybierała poszczególne piksele z obrazu i przenosiła je na tło okna. Z każdego piksela wartości składowych RGB zostaną odczytane z wykorzystaniem funkcji red(), green(), blue(). Następnie dla każdego piksela zostaną wyzerowane składowe barwy zielonej i niebieskiej. Aplikacja 1.3. funkcja rysująca void draw() { loadpixels(); //inicjacja pikseli ekranu img.loadpixels(); //inicjacja pikseli obrazu for (int y=0; y<height; y++ ) { for (int x=0; x<width; x++ ) { int loc = x + y*width; //połoŝenie piksela na obrazie // algorytm przetwarzania obrazu, odczytanie wartości składowych RGB dla // kaŝdego z pikseli obrazu float r = red(img.pixels [loc]); float g = green(img.pixels[loc]); float b = blue(img.pixels[loc]); pixels[loc] = color(r,0,0); //wyświetlenie pikseli, składowa r updatepixels(); //przeniesienie zmian na ekran 1.2.2. Interaktywne przetwarzanie obrazu Możliwość łatwego zaprogramowania interakcji z użytkownikiem pokazuje istotę praktycznego zastosowania Processingu. Kolejny przykład będzie dotyczył interaktywnej obróbki obrazu. Zadaniem jest napisanie programu, który będzie wgrywał określone zdjęcie na ekran i dokonywał przetworzenia wybranego przez użytkownika fragmentu. Na wybrany fragment zostanie nałożony prosty filtr operujący na pikselach i pozwalający na wykrywanie krawędzi.

8 Ćwiczenie P-3 Na początku zostaną zadeklarowane dwa obiekty klasy PImage. Jeden z nich należy skojarzyć z plikiem graficznym, na którym będziemy dokonywać przekształceń. Rozmiar okna zostanie dopasowany do rozmiaru obrazka. Aplikacja 1.4. deklaracja zmiennych, funkcja inicjująca i funkcja rysująca PImage img,img2; void setup() { img = loadimage( "Lilie wodne.jpg"); size(img.width,img.height); void draw() { Następnie zostanie obsłużone zdarzenie związane z ruchem kursora. Z kursorem zostanie powiązany prostokąt okno, w którym będzie nałożony odpowiedni filtr i którego położenie będzie zmieniało się wraz z ruchem kursora. Aplikacja 1.4. obsługa zdarzenia związanego z ruchem kursora void mousemoved(){ background(img); int WspX=mouseX; int WspY=mouseY; stroke(255,0,0); nofill(); strokeweight(2); rect(mousex-25,mousey-25,150,150); //rysowanie prostokąta Kolejne obsłużone zdarzenie będzie związane z naciśnięciem klawisza myszy. Zgodnie z postawionym zadaniem, po naciśnięciu przycisku na wybranym fragmencie obrazu zostanie dokonanie przetworzenie pikseli - filtracja. W tym celu zostanie zdefiniowana funkcja przetworzobraz(), do której będą przekazywane współrzędne górnego lewego rogu zaznaczonego fragmentu oraz jego szerokość i wysokość. Po przetworzeniu obrazu w zaznaczonym miejscu zostanie wyświetlony zmodyfikowany fragment. Aplikacja 1.4. obsługa zdarzenia związanego z naciśnięciem klawisza myszy void mousepressed(){ int WspX=mouseX; int WspY=mouseY; stroke(255,0,0); nofill(); strokeweight(2); przetworzobraz(wspx-25,wspy-25,150,150); image(img2,wspx-25,wspy-25); rect(mousex-25,mousey-25,150,150); Funkcja przetworzobraz() składa się z następujących zbiorów instrukcji. Najpierw z obiektem img2 zostanie powiązany pusty obszar o rozmiarze identycznym z rozmiarem przetwarzanego fragmentu obrazu i pikselach wyświetlanych w formacie RGB. Następnie zostaną załadowane piksele obydwu obrazów img2 i img1. W dwóch zagnieżdżonych pętlach

Ćwiczenie P-3 9 for zostaną przetworzone i przepisane zmodyfikowane piksele z obiektu img1 do obiektu img2. Ostatecznie zmiany pikseli drugiego obrazka (img2) zostaną utrwalone przy pomocy funkcji updatepixels(). Poszczególne piksele w wybranym fragmencie zostaną zmodyfikowane. Najpierw zostanie wybrany piksel i piksel sąsiadujący z nim z lewej strony. Z każdego z nich można odczytać wartość jasności korzystając z funkcji brightess(), a następnie nadać pierwszemu wybranemu pikselowi wartość koloru będącą wartością bezwzględną różnicy pomiędzy jego jasnością a jasnością najbliższego piksela z lewej strony. W ten sposób można łatwo wykryć pionowe krawędzie, ponieważ pomiędzy pikselami znajdującymi się na krawędzi występują największe różnice jasności. Aplikacja 1.4. funkcja do przetwarzania obrazu void przetworzobraz(int imgx, int imgy, int imgw,int imgh){ img2=createimage(imgw,imgh,rgb); img.loadpixels(); img2.loadpixels(); for (int y=imgy; y<imgy+imgh; y++ ) { for (int x=imgx; x<imgx+imgw; x++ ) { int loc=x+y*img.width; int loc2=x-imgx+(y-imgy)*imgw; //filtr wykrywanie krawędzi color pix=img.pixels[loc]; int leftloc=(x-1)+y*img.width; color leftpix = img.pixels[leftloc]; float diff = abs(brightness(pix) - brightness(leftpix)); img2.pixels[loc2] = color(diff); img2.updatepixels(); Przedstawiony przykład jest bardzo prosty. Jednak korzystając z tej metody można zaprojektować bardziej złożone metody filtracji obrazu. Wykorzystywane są wtedy informacje zawarte w większej liczbie sąsiadujących pikseli (Rys. 1.2), zaś wartości składowych koloru piksela są funkcją wartości składowych kolorów pikseli znajdujących się wokół niego. Rysunek 1.2. Położenie pikseli obrazu i ich współrzędne w wektorze pixels[]

10 Ćwiczenie P-3 W Processingu możliwe jest też zastosowanie predefiniowanych metod przetwarzania obrazu, które można wywołać stosując funkcję filter(mode) filter(mode, level) Parametr MODE mówi o sposobie filtracji (tabela 1.2), zaś parametr level odpowiada za jakość filtracji i może przyjmować wartości rzeczywiste lub całkowite. Rysunek 1.3. Okno aplikacji 1.4 (interaktywne przetwarzanie obrazu) Tabela 1.2. Wartości parametru MODE i opis sposobu przetwarzania obrazu. Wartość Opis THRESHOLD Konwertuje rysunek do czarnych i białych pikseli, w zależności od tego czy wartości koloru znajdują się powyżej czy poniżej granicy, określonej przez parametr level. Wartość tego parametru powinna znajdować się pomiędzy 0.0 (czarny) a 1.0 (biały), standardowa wartość to 0.5. GRAY Konwertuje kolory do odpowiadających im kolorów w skali szarości. INVERT Odwraca wartości barw składowych. POSTERIZE Ogranicza wartości kanałów w obrazie do liczby kolorów określonej przez parametr level. BLUR Dokonuje rozmycia gaussowskiego. Parametr level określa rozmiar rozmycia, standardowo ustawiony jest na 1. OPAQUE Ustawia kanał alpha na całkowitą przezroczystość. ERODE Zmniejsza jasne obszary o wartość podawaną jako parametr level. DILATE Powiększa jasne obszary o wartość podawaną jako parametr level. Filtry wywoływane przy pomocy funkcji filter() stosowane są do całego obrazka wyświetlanego na ekranie z wykorzystaniem funkcji image(). Filtrację najlepiej wykonywać od razu po wyświetleniu obrazka.

Ćwiczenie P-3 11 2. Oświetlenie W Processingu umożliwiono określenie oświetlenia sceny trójwymiarowej. Wszystkie funkcje z nim związane należy umieścić w funkcji rysującej, ponieważ oświetlenie jest inicjowane podczas każdego wywołania funkcji draw(). Podstawowa funkcja, lights(), ustawia domyślne wartości oświetlenia, tj. światło otaczające ( ambientlight(128,128,128) ), światło kierunkowe ( directionallight(128, 128, 128, 0, 0, -1) ), ogólny kształt stożka światła ( falloff(1, 0, 0) ) oraz połysku ( specular(0, 0, 0) ). Całe oświetlenie sceny można wyłączyć, korzystając z funkcji nolights(). 2.1. ŚWIATŁO OTACZAJĄCE Światło otaczające wypełnia równomiernie całą wyświetlaną scenę. Promienie padają ze wszystkich kierunków. Należy je wykorzystywać z innymi źródłami światła. Światło otaczające definiuje się przy pomocy funkcji ambientlight(). ambientlight(r, G, B) Parametry tej funkcji to wartości składowych RGB, określających barwę światła. Wszystkie parametry mogą być typu int lub float. 2.2. ŚWIATŁO KIERUNKOWE Światło kierunkowe pada z określonego kierunku. Powierzchnie, na które padają promienie pod kątem prostym są silniej oświetlone, natomiast jeśli kąt jest większy, to oświetlenie jest słabsze. Promienie odbijają się we wszystkich kierunkach od powierzchni, na którą padają. Światło kierunkowe definiuje się przy pomocy funkcji directionallight(). directionallight(r, G, B, nx, ny, nz) Parametry tej funkcji to wartości składowych RGB, oraz nx, ny, nz współrzędne określające kierunek źródła światła (nz = -1 oznacza, że światło pada z dołu sceny). Wszystkie parametry mogą być typu int lub float. 2.3. ŚWIATŁO PUNKTOWE Światło punktowe pada z określonego punktu sceny. Światło punktowe definiuje się przy pomocy funkcji pointlight(). pointlight(r, G, B, x, y, z) Parametry tej funkcji to wartości składowych RGB, x, y, z współrzędne źródła światła. Wszystkie parametry mogą być typu int lub float.

12 Ćwiczenie P-3 2.4. ŚWIATŁO SKONCENTROWANE Światło skoncentrowane pada z określonego punktu sceny, w określonym kierunku. Światło skoncentrowane definiuje się przy pomocy funkcji spotlight(). spotlight(int/float R, int/float G, int/float B, int/float x, int/float y, int/float z, int/float nx, int/float ny, int/float nz, float kąt, float koncentracja) Parametry tej funkcji to odpowiednio wartości składowych RGB, x, y, z współrzędne źródła światła, nx, ny, nz wartości określające kierunek rozchodzenia się światła, kąt kąt rozwarcia stożka światła, koncentracja wartość określająca intensywność źródła światła. 2.5. DODATKOWE FUNKCJE ZWIĄZANE Z OŚWIETLENIEM W Processingu zaimplementowano kilka dodatkowych funkcji związanych z własnościami oświetlenia. Część dotyczy własności źródła światła (tabela 2.1.), natomiast pozostałe dotyczą własności powierzchni, na którą pada światło (tabela 2.2.). Tabela 2.1. Funkcje związane z oświetleniem Funkcja Opis lightfalloff() Przy pomocy tej funkcji można ustawić trzy współczynniki określające kąt stożka światła w miejscu wygaszenia promieni. Dotyczy światła otaczającego, punktowego i skoncentrowanego. lightspecular() Funkcja określa kolor odbijanego światła i zależy od własności odbijających materiału. Wywoływana jest z trzema parametrami określającymi wartości składowych RGB. Tabela 2.2. Funkcje związane z własnościami materiału Funkcja Opis ambient() Funkcja określająca stopień pochłaniania promieni o określonych własnościach. Wywoływana może być z różną liczbą parametrów (zwykle trzema, określającymi wartości składowych RGB). specular() Funkcja określa kolor materiału zależny od kierunku światła. Wywoływana może być z różną liczbą parametrów (zwykle czterema, określającymi wartości składowych RGB i przezroczystość powierzchni). Pozwala uzyskać efekt podświetlenia emissive() Funkcja określa kolor światła emitowanego przez materiał. Wywoływana może być z różną liczbą parametrów (zwykle trzema, określającymi wartości składowych RGB). shininess() Funkcja określa ilościowo połysk materiału. Wywoływana jest z jednym parametrem.

Ćwiczenie P-3 13 2.6. OŚWIETLANIE SCENY Kolejny przykład służy do zobrazowania, w jaki sposób można oświetlić scenę. Dodatkowo zostanie pokazane jak tworzyć trójwymiarowe bryły definiując ich wierzchołki i boki. Na początku zostanie zainicjowane okno wraz z odpowiednim silnikiem 3D (P3D). Aplikacja 2.1. funkcja inicjująca void setup(){ size(800,400,p3d); Działanie funkcji draw() jest następujące. W środku okna w trzech wymiarach rysowany jest ostrosłup o podstawie kwadratu, obrócony o 30 stopni wokół każdej z osi. Oświetlenie bryły zależy od położenia kursora myszy. W funkcji rysującej zostanie określone światło otaczające, o wartościach składowych R=128, G=128, B=128. Następnie zostaną odczytane współrzędne kierunkowe światła (dirx, diry) zależne od położenia kursora, przeskalowane do zakresu [-1 1] i określone zostanie światło kierunkowe o wartościach składowych R=204, G=204, B=204. Dalsze instrukcje dotyczą przesunięcia układu współrzędnych do środka okna i dokonania obrotów wokół każdej osi o 30 stopni. Ostatecznie wywołana jest funkcja rysujostroslup(), która rysuje ostrosłup o podstawie kwadratu i czterech bokach będących trójkątami. Aplikacja 2.1. funkcja rysująca void draw(){ background(0,0,0); ambientlight(128,128,128); float diry = (mousey / float(height) - 0.5) * 2; float dirx = (mousex / float(width) - 0.5) * 2; directionallight(204, 204, 204, -dirx, -diry, 1); translate(width/2,height/2); rotatex(radians(30)); rotatey(radians(-30)); rotatez(radians(30)); rysujostroslup(); W funkcji rysujostroslup()wykorzystano bloki beginshape endshape() (opisane w podrozdziale 3.3), które definiują boki rysowanej bryły na podstawie podanych współrzędnych wierzchołków.

14 Ćwiczenie P-3 Aplikacja 2.1. funkcja rysujostroslup() void rysujostroslup(){ fill(255,0,0); nostroke(); beginshape(quads); vertex( 100, 0, 100); vertex( 100, 0, -100); vertex(-100, 0, -100); vertex(-100, 0, 100); endshape(); beginshape(triangles); //rysowanie boku 1 vertex(-100, 0, 100); vertex( 100, 0, 100); vertex(0, -150, 0); //rysowanie boku 2 vertex(100, 0, 100); vertex(100, 0, -100); vertex(0, -150, 0); //rysowanie boku 3 vertex(-100, 0, -100); vertex( 100, 0, -100); vertex(0, -150, 0); //rysowanie boku 4 vertex(-100, 0, -100); vertex(-100, 0, 100); vertex(0, -150, 0); endshape(); } // rysowanie podstawy Rysunek 2.1. Okno aplikacji 2.1.

Ćwiczenie P-3 15 3. Nakładanie tekstury 3.1. INFORMACJE PODSTAWOWE W Processingu istnieje możliwość nakładania tekstury na zdefiniowane kształty. Dotyczy to kształtów utworzonych z wierzchołków w blokach definiujących nowe kształty (beginshape() endshape() podrozdział 3.3). Tekstura jest fragmentem obrazu nałożonym na dany kształt. Obraz powinien być dodany do programu przed nałożeniem tekstury i skojarzony z obiektem klasy PImage. Do skojarzenia obrazu z teksturą należy wykorzystać funkcję texture(). texture(pimage img); gdzie img jest obiektem klasy PImage przechowującym dane o obrazie nakładanym jako tekstura. Wywołanie tej funkcji powinno znaleźć się wewnątrz bloku definiującego nowe kształty beginshape() endshape(), przed instrukcjami definiującymi wierzchołki. W przypadku nakładania tekstury kolor wypełnienia zdefiniowanego kształtu jest ignorowany. Zamiast tego stosowana może być funkcja tint() określająca kolor nakładanej tekstury. Nałożenie tekstury na określoną powierzchnię zależy od dwóch dodatkowych parametrów podawanych przy definiowaniu wierzchołków z wykorzystaniem funkcji vertex() (funkcja opisana w instrukcji 2). vertex(x, y, z, ox, oy) Dodatkowe parametry ox i oy określają w pikselach położenie na obrazie, nakładanym jako tekstura, punktu przyporządkowanego danemu wierzchołkowi. Położenie punktu jest określone względem górnego, lewego rogu obrazu. Wszystkie parametry mogą być typu int lub float. Po zdefiniowaniu wierzchołków i odpowiadających im punktów obrazu, wybrany fragment zostanie rozciągnięty na zadanej powierzchni. Możliwe jest nakładanie tekstury w dwóch trybach określanych przy pomocy dyrektywy texturemode(). texturemode(tryb) Parametr TRYB może przyjmować wartości IMAGE lub NORMALIZED. Domyślnym trybem jest IMAGE. W tym przypadku współrzędne punktów obrazu, nakładanego jako tekstura, podawane są w pikselach. Na przykład mając obraz o rozmiarach 100 200 pikseli i nakładając go w całości na powierzchnię prostokątną podawane punkty będą miały współrzędne (0,0),(0,100),(100,200),(0,200). Drugi tryb to NORMALIZED, który normalizuje rozmiar obrazu do współrzędnych z zakresu (0,1). Tak więc współrzędne punktów przykładowego obrazu będą następujące: (0,0),(0,1),(1,1),(0,1).

16 Ćwiczenie P-3 3.2. NAKŁADANIE TEKSTURY NA ZŁOŻONY KSZTAŁT Kolejna aplikacja służy do pokazania, jak można nakładać teksturę na złożony kształt. Działanie programu jest następujące. W środku okna w trzech wymiarach jest rysowany ostrosłup o podstawie trójkąta z nałożoną na każdy z boków teksturą. Sposób ustawienia bryły względem okna będzie zależał od ruchu myszy. Na początku zadeklarowano cztery obrazy, z których każdy będzie się pokazywał na poszczególnych bokach bryły. Następnie zadeklarowano zmienne określające położenie układu współrzędnych, który będzie się zmieniał wraz z ruchem kursora po ekranie. Aplikacja 3.1. deklaracja zmiennych. //deklaracja zmiennych przechowujących 4 obrazy nakładane jako tekstura PImage img1,img2,img3,img4; //deklaracja zmiennych związnych z połoŝeniem i sterowaniem ruchem bryły float rotx = 0.0, roty = 0.0; int ostx, osty; float distx = 0.0, disty = 0.0; W funkcji inicjującej określono rozmiary okna oraz silnik 3D. Następnie przyporządkowano każdemu obiektowi klasy PImage odpowiednie obrazy. Wcześniej muszą być one dodane do folderu aplikacji. Ostatnia linijka mówi, że współrzędne obrazów nakładanych jako tekstura będą znormalizowane. Aplikacja 3.1. funkcja inicjująca void setup(){ size(800,400,p3d); img1=loadimage("lilie wodne.jpg"); img2=loadimage("niebieskie gory.jpg"); img3=loadimage("zachod slonca.jpg"); img4=loadimage("zima.jpg"); texturemode(normalized); Funkcja rysująca składa się instrukcji określających wygląd okna programu oraz określających położenie układu współrzędnych. Wartości podawane jako parametry funkcji rotatex() i rotatey() zależą od położenia kursora na ekranie. Ostrosłup z nałożoną teksturą jest rysowany z wykorzystaniem funkcji rysujostrosluptekstura(). Na każdy z boków nakładany jest fragment innego obrazu. Ponieważ w bloku definicji nowego kształtu nakładana jest tylko tekstura określona przy pierwszym wywołaniu funkcji texture(), każdy z boków musi być zdefiniowany oddzielnie.

Ćwiczenie P-3 17 Aplikacja 3.1. funkcja rysująca void draw(){ background(255,255,255); nostroke(); translate(width/2,height/2); //przesunięcie bryły na środek okna rotatex(rotx+disty); //obrót bryły wokół osi OX rotatey(roty+distx); //obrót bryły wokół osi OY rysujostrosluptekstura(); Aplikacja 3.1. funkcja rysujostrosluptekstura() void rysujostrosluptekstura(){ beginshape(triangles); //rysowanie podstawy texture(img1); //określenie tekstury vertex( 100, 0, 100,0,0); vertex( 100, 0, -100,0,1); vertex(-100, 0, -100,1,1); endshape(); beginshape(triangles); //rysowanie boku 1 texture(img2); //określenie tekstury vertex( 100, 0, 100,0,0); vertex( 100, 0, -100,0,1); vertex(0, -150, 0,1,1); endshape(); beginshape(triangles); //rysowanie boku 2 texture(img3); //określenie tekstury vertex(100, 0, -100,0,0); vertex(-100, 0, -100,0,1); vertex(0, -150, 0,1,1); endshape(); beginshape(triangles); //rysowanie boku 3 texture(img4); //określenie tekstury vertex(-100, 0, -100,0,0); vertex( 100, 0, 100,0,1); vertex(0, -150, 0,1,1); endshape(); Ostatecznie zostaną zaprogramowane funkcje związane z ruchem myszy. W przypadku naciśnięcia klawisza myszy (mousepressed()) zapamiętane jest położenie kursora. Podczas ruchu kursora z wciśniętym klawiszem myszy (mousedragged()) zmieniane są wartości kątów obrotu bryły. Zwolnienie klawisza (mousereleased()) blokuje obraz.

18 Ćwiczenie P-3 Aplikacja 3.1. funkcje obsługujące zdarzenia związane z ruchem myszy void mousepressed(){ ostx = mousex; osty = mousey; } void mousedragged(){ distx = radians(mousex - ostx); disty = radians(osty - mousey); } void mousereleased(){ rotx += disty; roty += distx; distx = disty = 0.0; } Rysunek 3.1. Okno aplikacji 3.1. 4. Kamera W Processingu umożliwiono ustawienie kamery i określenie punktu, z którego obserwowana jest dana scena. W tym celu należy skorzystać z funkcji camera(). camera(int/float eyex, int/float eyey, int/float eyez, int/float centerx, int/float centery, int/float centerz, upx, upy, upz) Parametrami tej funkcji są eyex, eyey, eyez współrzędne położenia obserwatora, centerx, centery, centerz współrzędne położenia centrum sceny, upx, upy, upz określenie, która oś skierowana jest w górę sceny (wartości 0, 1, -1). Zmiana powyższych parametrów pozwala na ruch obserwatora względem sceny. Domyśle ustawienia kamery, obowiązujące jeśli nie podano żadnych parametrów, są następujące: camera(width/2.0, height/2.0, (height/2.0) / tan(pi*60.0 / 360.0), width/2.0, height/2.0, 0, 0, 1, 0) W Processingu umożliwiono także zaawansowane zarządzanie położeniem kamery, przy pomocy bloku begincamera() endcamera(). Bloki te nie mogą być zagnieżdżane.

Ćwiczenie P-3 19 Blok begincamera() endcamera()umożliwia zastosowanie transformacji (instrukcje translate(), rotate()) do kamery a nie obiektów na scenie. Funkcje związane z kamerą anulują wykonane wcześniej funkcje związane z przemieszczeniem układu współrzędnych. Z tego powodu najpierw należy ustawić kamerę (blok begincamera() endcamera()), a dopiero późnej dokonywać transformacji obiektów na scenie korzystając ze stosu macierzy przekształceń. 5. Zadania do samodzielnego wykonania 5.1. ZADANIE INTERAKTYWNE PRZETWARZANIE OBRAZU, c.d. Treść zadania: Podczas omawiania operacji na plikach graficznych zaproponowano aplikację do interaktywnej obróbki obrazu (podrozdział 2.4). Kolejnym zadaniem do samodzielnego wykonania będzie uzupełnienie tej aplikacji o: samodzielne zdefiniowanie rozmiaru okna, w którym dokonywane jest przekształcenie obrazu, wykorzystanie trzech filtrów wyświetlających poszczególne składowe RGB występujące w zaznaczonym fragmencie. wykorzystanie dwóch wybranych filtrów wywoływanych przy pomocy funkcji filter(). Przydatne informacje: Do narysowania okna, w którym znajduje się przetwarzany fragment obrazu wystarczy zmieniać położenie lewego górnego rogu (określającego położenie obrazu) i prawego dolnego rogu (określającego szerokość i wysokość okna). Do blokowania i odblokowywania punktów zaznaczanego obszaru można skorzystać z funkcji związanych z obsługą wciśnięcia klawisza myszy i ruchu kursora opisanych w programie do zmiany kształtu krzywych Beziera (instrukcja nr 2). Odpowiednie składowe RGB koloru można odczytać korzystając z funkcji red(), green(), blue()(tabela 1.1). Wybór odpowiedniego filtru można określić korzystając z klawiszy. Funkcje związane z obsługa klawiatury i sprawdzeniem, który klawisz został wciśnięty zostały opisane w instrukcji 1. Podczas wykonywania operacji z wykorzystaniem funkcji filter() przydatne może być użycie funkcji get() do skopiowania odpowiedniego fragmentu obrazka.

20 Ćwiczenie P-3 5.2. ZADANIE NAKŁADANIE TEKSTURY NA RUCHOME OBIEKTY Treść zadania: Należy napisać aplikację nakładającą różne tekstury na dwa sześciany poruszające się w przestrzeni. Sześcian pierwszy porusza się po orbicie wokół środka ekranu. Drugi sześcian porusza się po orbicie wokół pierwszego sześcianu. Obydwa sześciany obracają się w trzech osiach z różnymi prędkościami. Rysowanie każdego sześcianu należy zrealizować przy pomocy uniwersalnej funkcji o następującym nagłówku void szescian(float bok,pimage tekstura) gdzie bok - długość jednego boku sześcianu, tekstura obrazek nakładany jako tekstura na każdy z boków. 6. Literatura [1] Bożena Pawlak Processing nowe narzędzie do tworzenia apletów. Analiza możliwości na przykładzie apletów z dziedziny grafiki komputerowej, Praca dyplomowa inżynierska, Wydział Mechatroniki, 2005/2006. [2] Ira Greenberg: Processing: Creative Coding and Computational Art, Friendsof, 2007. [3] Casey Reas, Ben Fry, Processing: A Programming Handbook for Visual Designers and Artists, MIT Press, 2007. [4] Daniel Shiffman: Learning Processing. A Beginners Guide to Programming Images, Animation and Interaction, Elsevier, 2008. [5] Pomoc środowiska Processing.