Cinder

Cinder jest biblioteką wspomagającą programistę w tworzeniu kreatywnego oprogramowania. Skupia się na ułatwieniu wszelkich operacji związanych z wizualnym aspektem programu. Poprzez liczne dodatki – bloki, niesamowicie przyspiesza realizację projektu.

Krótki wykład pokazujący możliwości tej biblioteki, prowadzony przez twórcę, Andrew Bell’a.

Obecnie duży wkład w rozwój ma firma Barbarian Group.
Continue reading →

frame-substract-bkg

Processing z OpenCV

Poprzednio wspomniałem, że planuję użyć OpenCV.  Dlatego też, tym razem skupię się na obróbce obrazu z kamery właśnie przy użyciu tej biblioteki.

kola-na-scianie-łapa

Brązowe i niebieskie plamy, to uchwyty na ścianie. Kółka z numerami są wyświetlane przez rzutnik. Celem jest wykrycie przysłonięcia, lub konkretniej, wykrycia kolizji  z kołem. Na początek pierwszy etap, czyli przygotowanie obrazu do analizy.

Continue reading →

Processing

processing-intro

Po zainstalowaniu Processing i ustawieniu wszystkiego zgodnie z moim przyzwyczajeniem, nadszedł czas na pierwsze linie kodu. Aplikacja w processing opiera się przede wszystkim na dwóch funkcjach:

  • setup()
  • draw()

Funkcja setup() służy do ustalenia warunków początkowych. Wywoływana jest jednorazowo po uruchomieniu aplikacji. Umieszcza się tam wszystko to co potrzebujemy i możemy zainicjować, załadować, zanim nasz program zacznie działać na dobre.

void setup()
{
    size(960, 540);
}

Użycie funkcji size() w setup()pozwala ustawić początkowy rozmiar okna. Po uruchomieniu takiej aplikacji, mamy spektakularny efekt w postaci pustego okna.

Funkcja draw() wywoływana jest cyklicznie, aż do zamknięcia aplikacji. Jest to połowiczna prawda, bo można zablokować wywoływanie tej funkcji, ale nie ma to teraz żadnego znaczenia. Domyślna częstotliwość dla draw() to 60Hz. Zmianę można wywołać poprzez funkcje frameRate().  Po uruchomieniu aplikacji zobaczymy takie okno
processing-emptywindow
Mój projekt ma bazować na przetwarzaniu obrazu z kamery, więc należałoby dodać jej obsługę. Potrzebny do tego jest moduł Video. W przypadku Processing bazuje on na znanej bibliotece GStreamer. Instalacja poprzez „Contributon Manager” znacząco upraszcza sprawę.

Na początek planuję używać tego co mam pod ręką, czyli kamerę wbudowaną w laptopa.  Nie jest zbyt spektakularna jeśli chodzi o parametry, 30 klatek w rozdzielczości 1280×720 będzie wystarczające. Sądzę, że nawet nieco mniej będzie wygodniejsze. Mniej danych, szybciej się policzy. Skoro kamera nie pracuje szybciej niż 30Hz to częstotliwość dla funkcji draw() ustawię też na 30. Czyli będzie to wyglądało następująco:

 

import processing.video.*;

Capture video;

void setup()
{
    size(960, 540);
    frameRate(30);
    
    video = new Capture(this, width, height);
    video.start();   // uruchomienie kamery
}

Zmienne systemowe – width, height zawierają odpowiednio szerokość i wysokość okna aplikacji. Zmienna globalna video zawiera obiekt kontrolujący obsługę kamery. Za wyświetlenie obrazu z kamery w oknie odpowiedzialna będzie funkcja draw():

void draw()
{
    if ( video.available() )  //dostępna klatka z kamery
        video.read();         //odczyt klatki
    image(video, 0, 0);
}

Konstrukcja aplikacji z podziałem na setup() i draw() jest mniej przejrzysta. Według mnie przydało by się wprowadzić jeszcze wyraźnie zaznaczony update(). Czyli kod, który aktualizuje stan naszej aplikacji, ale nie generuje obrazu. W taki sposób nieco bardziej będzie to przypominało standardową pętlę zdarzeń z silnika gier.

void update()
{
    if ( video.available() )  //dostępna klatka z kamery
        video.read();         //odczyt klatki
}

void draw()
{
    update();

    image(video, 0, 0);
}

Uruchomienie tego kodu wyświetli okno z obrazem z kamery. Niewiele kodu, a już coś działa.

 

processing-camwindow

Pracuję często z domu i niestety mam tą wątpliwą przyjemność służyć za łoże dla jednego z kotów. Dla dodania uroku tej sytuacji, nadmienię, że mam całkiem sporą alergię na sierść kota. Na screenie wyświetlany obraz z kamery w oknie.

Funkcja image()  rysuje w oknie zadany obraz. Definiujemy górny lewy róg, oraz opcjonalnie szerokość i wysokość. Według dokumentacji nie należy do najszybszych. Może m.in. skalować wyświetlany obraz. Wersja bardziej bezpośrednia, to użycie set().

void draw()
{
    update();
    set(0, 0, video);
}

Wracając do meritum, niespecjalnie spektakularny efekt, ale do przodu. Kolejny etap to obróbka obrazu. Nie mam w planie pisać wszystkiego od nowa. Znacznie mądrzejsi ode mnie stworzyli zacną bibliotekę OpenCV i z niej zamierzam niedługo skorzystać.

Wybór technologii

DSP2016 logo RGB color-4

Zastanawiając się nad tym, czego mógłbym użyć do projektu, od razu do głowy wpadł mi Processing. Czytałem sporo o tym oprogramowaniu  i wydaje się bardzo przyjemne do prototypowania. Jest to zintegrowane środowisko(IDE) do nauki i tworzenia oprogramowania w kontekście sztuki video. Do maksimum uproszczono operowanie na grafice. Mnogość dodatkowych bibliotek sugeruje, że warto iść w tym kierunku. Processing używa Javy. Niestety jestem daleki od bycia biegłym w tym języku. Myślę, że na podstawowym poziomie nie ma to najmniejszego znaczenia.

Sama idea tego typu rozwiązań stała się na tyle ciekawa, że na bazie Processing powstał projekt Wiring, upraszczający tworzenie oprogramowania na mikrokontrolery. Szczęśliwie wymieniono Javę na C++. Choć chyba najbardziej znanym projektem, jest Arduino, które bazuje na Wiring. Szybkie stworzenie urządzenia w opartego o mikrokontroler AVR jest banalnie proste.  Zrobiłem kilka urządzeń na Arduino i działają bez problemu od dość dawna. Co prawda oryginalny edytor jest dla mnie średnio wygodny. Przy odrobinie chęci skonfigurowanie SublimeText czy nawet AtmelStudio nie jest problemem, a wygoda pracy znacząco się podnosi.

Skoro mój projekt zawiązany jest w pewnym stopniu z rozszerzoną rzeczywistością, to poniżej przykład co można zrobić w Processing.

 

Przygotowanie do pracy z Processing

Ze strony https://processing.org/download ściągam paczkę. Aktualnie pracuję pod Windows, więc tym razem będzie to wersja dedykowana pod ten system. Nie zaszkodzi spoglądnąć na release notes. Szczególnie, że w paragrafie „Things That May Break Your 2.x Sketches” widnieje uwaga dotycząca użycia size(). Miło wiedzieć o takich kwiatkach.

Wszystkie moje projekty, czy cokolwiek czym się zajmuję, umieszczam w katalogu workspace. Struktura jest zazwyczaj prosta. W katalogu o nazwie projektu umieszczam wszystkie związane z nim elementy, czyli oprogramowanie/biblioteki(jeśli jest to możliwe), dokumentacje, moje notatki i oczywiście kod źródłowy. Dzięki takiej strukturze, łatwo stworzyć kompletne repozytorium w Git. Tak samo łatwo migrować na inną maszynę. Co prawda pod Windows sprawa nie zawsze jest tak prosta, bo jednak czasem muszę coś instalować i śmiecić katalog Program Files, niemniej jednak rozwiązanie sprawdza się od lat.

Czyli tym razem to jest c:workspaceCinderClimb i tam rozpakowuję archiwum z Processing. Aktualna wersja to 3.0.2

Po uruchomieniu środowiska, dostępny jest edytor, więc pracę można zacząć od razu.

image02

Przy okazji okazało się, ze Processing może też używać Pythona. Programuję w tym języku od wielu lat, to była by kusząca opcja. Jednak zdecydowałem się pozostać przy Javie. Nie chciało mi się szukać informacji na temat dostępnych bibliotek, a skoro jest to raczej nowa cecha środowiska to pewnie słabo z dodatkami. Nie mówię, Python sam z siebie jest ślicznie opakowany bibliotekami, „batteries included”. No, ale…

Instalacja bibliotek okazuje się banalnie prosta. Wbudowany w edytor Contribution Manager listuje wszystko co jest dostępne.

image01

Na razie nic nie instaluje, bo muszę się choć minimalnie zaznajomić z się”architekturą”. Pocieszające jest to, że środowisko udostępnia jakieś sensowne zarządzanie bibliotekami. Przynajmniej tak to na pierwszy rzut oka wygląda.

Samo skompilowanie pustego projektu działa bez zarzutu i po uruchomieniu pojawia się puste okno. Następny wpis będzie dotyczył wypełnienia pustego projektu pierwszym kodem.

Cinder climb

DSP2016 logo RGB color-1

Cinder Climb

Od mniej więcej roku wspinam się i na ścianie staram się być co najmniej 2 razy w tygodniu. Niesamowicie wciągające zajęcie. Niedawno znajomy umieścił na FB link do bardzo ciekawego połączenia wspinania z komputerem. Gra zręcznościowa rozgrywana bezpośrednio na ścianie.

Nie szukając za wiele informacji na sieci, postanowiłem napisać coś podobnego. Dodatkowo pojawił się na stronie Macieja Aniserowcza konkurs „Daj się poznać”. Niemal idealnie dopasowany do tego typu projektu. Przez 3 miesiące będę publikował informacje o postępie prac nad moim rozwiązaniem, a kod od będzie na githubie. Kilka lat temu zajmowałem się programowaniem gier, więc będzie to miłe przypomnienie sobie starych klimatów.

Bardzo wstępne założenia projektu

Gra polega na łapaniu kolejnych punktów, wyświetlanych na ścianie wspinaczkowej, na czas. Punkty wyświetlane są  za pomocą rzutnika. Detekcja czy gracz dotknął punktu realizowana jest na podstawie obrazu z kamery.

Wstępnie użyję środowiska Processing. Co prawda Java nie jest moją mocną stroną, ale na wykonanie samego proof-of-concept  może być w porządku. Jeśli to rozwiązanie nie będzie mi odpowiadać, to użyję libCinder albo openFrameworks. W tym wypadku będzie to już C++.

Na tym niezmiernie poglądowym rysunku, okolice mojego szczytu możliwości rysowniczych, przedstawiam teoretyczny układ planowanego użycia sprzętu.

Rzutnik rzuca na ścianę wszelkie potrzebne informacje. Kamera umieszczona obok rzutnika, analizuje co się dzieje i czy wspinacz daje radę. Oczywiście wszystko spięte z komputerem.

Następny wpis będzie już konkretniej o wyborze technologii.