pierwsze kroki z Kinect i przetwarzaniem

Sensor Microsoft Kinect to urządzenie peryferyjne (przeznaczone dla komputerów XBox i windows), które działa podobnie jak kamera internetowa. Jednak oprócz zapewnienia obrazu RGB, zapewnia również mapę głębi. Oznacza to, że dla każdego piksela widzianego przez sensor Sensor Kinect mierzy odległość od sensora. To sprawia, że różne problemy z widzeniem komputerowym, takie jak usuwanie tła, wykrywanie plam i łatwiejsze i przyjemniejsze!

sam sensor Kinect mierzy tylko kolor i głębię. Jednak, gdy te informacje są na komputerze, wiele więcej można zrobić, jak” szkielet ” śledzenia (czyli wykrywanie modelu osoby i śledzenie jej ruchy). Aby wykonać śledzenie szkieletu, musisz użyć Kinect V2 processing libray opracowanego przez Thomasa Lenglinga tylko dla systemu windows. Jeśli jednak korzystasz z komputera Mac i chcesz tylko surowych danych z Kinect, masz szczęście! Ta biblioteka używa sterowników libfreenect i libfreenect2 open source, aby uzyskać dostęp do tych danych dla systemu Mac OS X (wkrótce Wsparcie dla systemu windows).

jakiego sprzętu potrzebuję?

najpierw potrzebujesz” samodzielnego „kinect’ a. Nie musisz kupować Xboxa.

  • samodzielny Sensor Kinect v1. Wierzę, że ten jest dostarczany z zasilaczem, więc nie potrzebujesz osobnego adaptera wymienionego obok. Jeśli jednak masz kinect v1 dostarczony z konsolą XBox, nie będzie on zawierał zasilacza sensora Kinect.
  • samodzielny Sensor Kinect v2. Prawdopodobnie potrzebujesz również adaptera Kinect dla systemu Windows. Nie daj się zrzucić, chociaż mówi o systemie windows, To pozwoli Ci podłączyć go do komputera mac przez USB. Na koniec upewnij się, że komputer obsługuje USB 3. Większość nowoczesnych maszyn tak, ale jeśli nie jesteś pewien, możesz dowiedzieć się więcej tutaj dla Mac OS X.

kilka dodatkowych uwag na temat różnych modeli:

  • Kinect 1414: jest to oryginalny kinect i współpracuje z biblioteką udokumentowaną na tej stronie w serii Processing 3.0 beta.
  • Kinect 1473: wygląda identycznie jak 1414, ale jest to zaktualizowany model. Powinna działać z tą biblioteką, ale nie mam jej do przetestowania. Proszę dać mi znać, jeśli tak, czy nie!
  • Kinect dla Windows Wersja 1: ???? Pomóc? Czy to działa?
  • Kinect dla systemu Windows Wersja 2: jest to nowy kinect marki z wszystkimi funkcjami dostępnymi w Kinect XBox One. Współpracuje również z tą biblioteką!

SimpleOpenNI

Możesz również rozważyć użycie biblioteki SimpleOpenNI i przeczytać książkę Grega Borensteina Making Things See. OpenNI posiada funkcje (Śledzenie szkieletu, rozpoznawanie gestów itp.), które nie są dostępne w tej bibliotece. Niestety, OpenNI został niedawno zakupiony przez Apple i chociaż myślałem, że został zamknięty, wydaje się, że są pewne wysiłki, aby go ożywić!. Nie jest jasne, jaka będzie przyszłość OpenNI i SimpleOpenNI.

jestem gotowy, aby zacząć już teraz

najprostszym sposobem zainstalowania biblioteki jest szkic Menedżera wkładów przetwarzania → Importuj Biblioteki → Dodaj bibliotekę i wyszukaj „Kinect”. Pojawi się przycisk o nazwie „zainstaluj”.Jeśli chcesz go zainstalować ręcznie, Pobierz najnowszą wersję i rozpakuj ją w folderze biblioteki. Uruchom ponownie przetwarzanie, otwórz jeden z przykładów w folderze przykłady i możesz już iść!

Co To jest przetwarzanie?

Processing to język i środowisko programowania open source dla osób, które chcą tworzyć obrazy, animacje i interakcje. Początkowo opracowany, aby służyć jako szkicownik programowy i uczyć podstaw programowania w kontekście wizualnym, przetwarzanie przekształciło się również w narzędzie do generowania gotowej pracy zawodowej. Obecnie istnieją dziesiątki tysięcy studentów, artystów, projektantów, badaczy i hobbystów, którzy używają przetwarzania do nauki, prototypowania i produkcji.

co jeśli nie chcę używać przetwarzania?

jeśli dobrze ci z C++ to proponuję rozważyć użycie openFrameworks lub Cinder z Kinect. Środowiska te mają pewne dodatkowe funkcje, a także mogą uzyskać przewagę szybkości C++ podczas przetwarzania danych głębi itp.:

  • ofxKinect
  • Kinect
  • więcej zasobów z: projektu OpenKinect

jaki kod napisać?

pierwszą rzeczą jest umieszczenie odpowiednich instrukcji importu na górze kodu:

import org.openkinect.processing.*;

oraz odniesienie do obiektu Kinect, tj.

Kinect kinect;

następnie w setup() możesz zainicjować ten obiekt kinect:

void setup() { kinect = new Kinect(this); kinect.initDevice();}

jeśli używasz Kinect v2, użyj zamiast tego obiektu Kinect2.

Kinect2 kinect2;void setup() { kinect2 = new Kinect2(this); kinect2.initDevice();}

po wykonaniu tej czynności możesz zacząć uzyskiwać dostęp do danych z sensora kinect. Obecnie biblioteka udostępnia dane na pięć sposobów:

  • PImage (RGB) z kamery kinect.
  • PImage (grayscale) z kamery kinect ir.
  • PImage (grayscale) z jasnością każdego piksela odwzorowaną na głębokość (jaśniejszą = bliżej).
  • PImage (RGB) z odwzorowaniem barwy każdego piksela na głębokość.
  • int array z surowymi danymi głębi (11 bitowych liczb od 0 do 2048).

spójrzmy na to po kolei. Jeśli chcesz używać Kinect tak jak zwykłej starej kamery internetowej, możesz uzyskać dostęp do obrazu wideo jako PImage!

PImage img = kinect.getVideoImage();image(img, 0, 0);

możesz po prostu poprosić o ten obraz w draw(), jednak jeśli możesz również użyć videoEvent(), aby wiedzieć, kiedy nowy obraz jest dostępny.

void videoEvent(Kinect k) { // There has been a video event!}

jeśli chcesz obraz IR:

kinect.enableIR(true);

dzięki kinect v1 nie można uzyskać zarówno obrazu wideo, jak i obrazu podczerwieni. Oba są przekazywane z powrotem za pomocą getVideoImage (), więc ten, który był ostatnio włączony, będzie tym, który otrzymasz. Jednak w przypadku Kinect v2 oba są dostępne jako oddzielne metody:

PImage video = kinect2.getVideoImage();PImage ir = kinect2.getIrImage();

teraz, jeśli chcesz uzyskać obraz głębi, możesz poprosić o obraz w skali szarości:

PImage img = kinect.getDepthImage();image(img, 0, 0);

jak również surowe dane głębokości:

int depth = kinect.getRawDepth();

w przypadku kinect v1 wartości głębokości raw mieszczą się w zakresie od 0 do 2048, w przypadku kinect v2 zakres wynosi od 0 do 4500.

aby uzyskać obraz głębi kolorów, użyj kinect.enableColorDepth(true);. Podobnie jak w przypadku obrazu wideo, w razie potrzeby możesz uzyskać dostęp do wydarzenia głębi.

void depthEvent(Kinect k) { // There has been a depth event!}

niestety, b / C Kamera RGB i kamera na podczerwień nie znajdują się fizycznie w tym samym miejscu, występuje problem z widzeniem stereo. Piksel XY na jednym obrazie nie jest tym samym XY na obrazie z kamery o cal po prawej stronie. Kinect v2 oferuje tak zwany „zarejestrowany” obraz, który wyrównuje wszystkie wartości głębi z kamerami RGB. Można to uzyskać w następujący sposób:

PImage img = kinect2.getRegisteredImage()

wreszcie, dla kinect v1 (ale nie v2), można również dostosować kąt kamery za pomocą metody setTilt().

float angle = kinect.getTilt();angle = angle + 1;kinect.setTilt(angle);

oto wszystkie przydatne funkcje, które mogą być potrzebne do korzystania z przetwarzającej biblioteki kinect:

  • initDevice() — Uruchom wszystko (wideo, głębokość, IR)
  • activateDevice(int) – Aktywuj określone urządzenie, gdy podłączonych jest wiele urządzeń
  • initVideo() — uruchom tylko wideo
  • enableIR(boolean) — Włączanie lub wyłączanie obrazu z kamery na podczerwień (tylko w wersji v1)
  • initDepth() — tylko głębokość startu
  • enableColorDepth(boolean) — Włączanie lub wyłączanie wartości głębi jako kolorowego obrazu
  • enableMirror(boolean) — odwzorowanie obrazu i danych głębi (tylko w wersji v1)
  • PImage getVideoImage() — Pobierz obraz wideo RGB (lub IR dla wersji v1)
  • PImage getIrImage() — Pobierz obraz IR (tylko v2)
  • PImage getDepthImage() — pobierz mapę głębokości obraz
  • PImage getRegisteredImage() — Pobierz zarejestrowany obraz głębi (tylko w wersji 2)
  • int getRawDepth() — Pobierz surowe dane głębi
  • float getTilt() — uzyskaj aktualny kąt czujnika (od 0 do 30 stopni) (tylko v1)
  • setTilt(float) — regulacja kąta czujnika (od 0 do 30 stopni) (tylko v1)

dla wszystkich innych, można również spojrzeć na Javadoc reference.

przykłady

istnieją cztery podstawowe przykłady zarówno dla v1, jak i v2.

wyświetlanie obrazów RGB, IR i głębi

kod dla v1:Rgbdepthtest

kod dla v2:RGBDepthTest2

ten przykład wykorzystuje wszystkie wymienione powyżej funkcje do wyświetlania danych z sensora kinect.

wiele urządzeń

zarówno v1, jak i V2 mają obsługę wielu kinect.

kod dla v1:MultiKinect

kod dla V2:MultiKinect2

chmura punktów

kod dla v1: PointCloud

kod dla v2: PointCloud

tutaj robimy coś nieco bardziej wymyślnego. Po pierwsze, używamy możliwości przetwarzania 3D do rysowania punktów w przestrzeni. Będziesz chciał zapoznać się z translate(), rotate(), pushMatrix (), popMatrix (). Ten samouczek jest również dobrym miejscem na początek. Ponadto w przykładzie używa się Pvektora do opisania punktu w przestrzeni 3D. Więcej tutaj: Tutorial PVector.

prawdziwe dzieło tego przykładu jednak wcale nie pochodzi ode mnie. Wartości głębi surowej z kinect nie są wprost proporcjonalne do głębokości fizycznej. Raczej skalują się z odwrotnością głębokości według tego wzoru:

depthInMeters = 1.0 / (rawDepth * -0.0030711016 + 3.3309495161);

zamiast wykonywać te obliczenia cały czas, możemy wstępnie obliczyć wszystkie te wartości w tabeli wyszukiwania, ponieważ istnieje tylko 2048 wartości głębokości.

float depthLookUp = new float;for (int i = 0; i < depthLookUp.length; i++) { depthLookUp = rawDepthToMeters(i);}float rawDepthToMeters(int depthValue) { if (depthValue < 2047) { return (float)(1.0 / ((double)(depthValue) * -0.0030711016 + 3.3309495161)); } return 0.0f;}

podziękowania dla Matthew Fishera za powyższy wzór. (Uwaga: aby wyniki były dokładniejsze, musisz skalibrować konkretne urządzenie kinect, ale formuła jest dla mnie wystarczająco bliska, więc na razie się jej trzymam. Więcej o kalibracji za chwilę.)

wreszcie możemy narysować kilka punktów na podstawie wartości głębokości w metrach:

 for(int x = 0; x < w; x += skip) { for(int y = 0; y < h; y += skip) { int offset = x + y * kinect.width; // Convert kinect data to world xyz coordinate int rawDepth = depth; PVector v = depthToWorld(x, y, rawDepth); stroke(255); pushMatrix(); // Scale up by 200 float factor = 200; translate(v.x * factor, v.y * factor, factor-v.z * factor); // Draw a point point(0,0); popMatrix(); } }

śledzenie średnich punktów

prawdziwa magia Kinecta tkwi w jego możliwościach widzenia komputerowego. Dzięki informacjom o głębi możesz robić różne zabawne rzeczy, takie jak powiedzieć: „tło jest czymś więcej niż 5 stóp. Zignoruj to!”Bez głębi usuwanie tła wymaga wszelkiego rodzaju żmudnych porównań pikseli. Jako szybką demonstrację tego pomysłu, oto bardzo prosty przykład, który oblicza średnią lokalizację XY dowolnych pikseli przed danym progiem głębokości.

Source for v1: AveragePointTracking

Source for v2: AveragePointTracking2

w tym przykładzie deklaruję dwie zmienne, aby zsumować wszystkie odpowiednie x i y oraz jedną zmienną, aby śledzić, ile ich jest.

float sumX = 0;float sumY = 0;float count = 0;

następnie, gdy znajdziemy dany punkt zgodny z naszym progiem, dodaję x i y do sumy:

 if (rawDepth < threshold) { sumX += x; sumY += y; count++; }

kiedy skończymy, obliczymy średnią i narysujemy punkt!

if (count != 0) { float avgX = sumX / count; float avgY = sumY / count; fill(255, 0, 0); ellipse(avgX, avgY, 16, 16);}

czego brakuje?

  • wszystko jest śledzone przez problemy z github.

FAQ

  1. jakie są cienie w obrazie głębi (v1)? Diagram cieni Kinect
  2. jaki jest zakres głębokości, który kinect widzi? (v1) ~0,7-6 metrów lub 2,3-20 stóp. Uwaga otrzymasz czarne piksele (lub surową wartość głębokości 2048) w obu elementach, które są zbyt daleko i zbyt blisko.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.