aan de slag met Kinect en Processing

de Microsoft Kinect-sensor is een randapparaat (ontworpen voor Xbox-en windows-pc ‘ s) dat vergelijkbaar is met een webcam. Echter, naast het verstrekken van een RGB-Afbeelding, Het biedt ook een dieptemap. Voor elke pixel die door de sensor wordt gezien, meet de Kinect de afstand tot de sensor. Dit maakt een verscheidenheid aan computer visie problemen zoals achtergrond verwijdering, blob detectie, en meer eenvoudig en leuk!

de Kinect-sensor zelf meet alleen kleur en diepte. Echter, zodra die informatie is op uw computer, veel meer kan worden gedaan zoals “skelet” tracking (dwz het opsporen van een model van een persoon en het bijhouden van zijn/haar bewegingen). Om skeleton tracking te doen moet je Thomas Lengling ‘ s Windows-only Kinect v2 processing libray gebruiken. Echter, als je op een Mac en alles wat je wilt is ruwe gegevens van de Kinect, je hebt geluk! Deze bibliotheek gebruikt libfreenect en libfreenect2 open source drivers om toegang te krijgen tot die gegevens voor Mac OS X (windows-ondersteuning komt binnenkort).

welke hardware heb ik nodig?

eerst hebt u een “stand-alone” kinect nodig. U hoeft geen Xbox te kopen.

  • Standalone Kinect Sensor v1. Ik geloof dat deze wordt geleverd met de voeding, zodat u geen aparte adapter nodig hebt die hierna wordt vermeld. Als u echter een kinect v1 hebt die bij een XBox is geleverd, wordt de Kinect-Sensorvoeding niet meegeleverd.
  • Standalone Kinect Sensor v2. Je hebt waarschijnlijk ook de Kinect Adapter voor Windows nodig. Niet worden afgeworpen, hoewel het zegt windows, dit zal u toelaten om het aan te sluiten op uw mac via USB. Tot slot, u zult ook willen ervoor zorgen dat uw computer ondersteunt USB 3. De meeste moderne machines wel, maar als u niet zeker bent kunt u hier meer te weten komen voor Mac OS X.

enkele aanvullende opmerkingen over verschillende modellen:

  • Kinect 1414: dit is de originele kinect en werkt met de bibliotheek gedocumenteerd op deze pagina in de Processing 3.0 beta serie.
  • Kinect 1473: dit lijkt identiek aan de 1414, maar is een bijgewerkt model. Het zou moeten werken met deze bibliotheek, maar ik heb er geen om te testen. Laat het me weten als het wel of niet!
  • Kinect voor Windows versie 1: ???? Helpen? Werkt deze?
  • Kinect voor Windows versie 2: Dit is de gloednieuwe kinect met alle functies in de Kinect van XBox One. Werkt ook met deze bibliotheek!

SimpleOpenNI

u kunt ook overwegen de simpleopenni bibliotheek te gebruiken en Greg Borenstein ‘ s Making Things See boek te lezen. OpenNI heeft functies (skelet tracking, gebarenherkenning, enz.) die niet beschikbaar zijn in deze bibliotheek. Helaas, OpenNI werd onlangs gekocht door Apple en, terwijl ik dacht dat het was gesloten, naar beneden lijken er een aantal inspanningen om het te doen herleven!. Het is onduidelijk wat de toekomst zal zijn van OpenNI en SimpleOpenNI.

ik ben nu klaar om aan de slag te gaan

de makkelijkste manier om de bibliotheek te installeren is met de sketch voor het beheer van bijdragen → bibliotheken importeren → bibliotheek toevoegen en zoeken naar “Kinect”. Er verschijnt een knop met het label “installeren”.Als u het handmatig wilt installeren, download dan de meest recente release en pak het uit in de map Bibliotheken. Herstart de verwerking, open een van de voorbeelden in de map voorbeelden en je bent klaar om te gaan!

Wat is verwerking?

Processing is een open source programmeertaal en omgeving voor mensen die afbeeldingen, animaties en interacties willen maken. Aanvankelijk ontwikkeld om te dienen als een software schetsboek en om de grondbeginselen van computerprogrammeren te leren binnen een visuele context, is de verwerking ook geëvolueerd tot een hulpmiddel voor het genereren van afgewerkt professioneel werk. Tegenwoordig zijn er tienduizenden studenten, kunstenaars, ontwerpers, onderzoekers en hobbyisten die Processing gebruiken voor leren, prototyping en productie.

wat als ik geen verwerking wil gebruiken?

als u vertrouwd bent met C++, stel ik voor dat u openFrameworks of Cinder met de Kinect gebruikt. Deze omgevingen hebben een aantal extra functies en je kan ook een C++ snelheidsvoordeel krijgen bij het verwerken van de dieptegegevens, enz.:

  • Ofxkinect
  • Kinect CinderBlock
  • meer bronnen van: het OpenKinect-Project

welke code schrijf ik?

het eerste ding is om de juiste import statements bovenaan uw code op te nemen:

import org.openkinect.processing.*;

evenals een verwijzing naar een Kinect object, d.w.z.

Kinect kinect;

dan kunt u in setup() dat kinect-object initialiseren:

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

als u een Kinect v2 gebruikt, gebruikt u in plaats daarvan een Kinect2-object.

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

zodra u dit hebt gedaan, kunt u toegang krijgen tot gegevens van de kinect-sensor. Op dit moment stelt de bibliotheek op vijf manieren gegevens voor u beschikbaar:

  • PImage (RGB) van de kinect videocamera.
  • PImage (grayscale) van de Kinect IR-camera.
  • PImage (grayscale) waarbij de helderheid van elke pixel is toegewezen aan diepte (helderder = dichter).
  • PImage (RGB) waarbij de tint van elke pixel is toegewezen aan diepte.
  • int array met ruwe dieptegegevens (11-bits getallen tussen 0 en 2048).

laten we deze één voor één bekijken. Als u de Kinect net als een gewone oude webcam wilt gebruiken, kunt u het videobeeld openen als een PImage!

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

u kunt deze afbeelding in draw() vragen, maar als u ook videoEvent() kunt gebruiken om te weten wanneer een nieuwe afbeelding beschikbaar is.

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

Als u de IR-afbeelding wilt:

kinect.enableIR(true);

met kinect kan v1 niet zowel het videobeeld als het IR-beeld krijgen. Ze zijn beide doorgegeven via getVideoImage() dus welke was het meest recent ingeschakeld is degene die je krijgt. Echter, met de Kinect v2, ze zijn beide beschikbaar als afzonderlijke methoden:

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

nu, als u de diepteafbeelding wilt, kunt u de grijswaardenafbeelding aanvragen:

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

evenals de ruwe dieptegegevens:

int depth = kinect.getRawDepth();

voor de kinect v1 ligt het ruwe dieptebereik tussen 0 en 2048, voor de kinect v2 ligt het bereik tussen 0 en 4500.

gebruik kinect.enableColorDepth(true);voor de afbeelding met kleurdiepte. En net als bij het videobeeld, is er een diepte event die je kunt openen indien nodig.

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

helaas bevinden b / c De RGB camera en de IR camera zich niet fysiek op dezelfde plek, er is een stereo vision probleem. Pixel XY in een afbeelding is niet hetzelfde XY in een afbeelding van een camera een centimeter naar rechts. De Kinect v2 biedt een zogenaamde “geregistreerde” afbeelding die alle diepte waarden uitlijnt met de RGB camera degenen. Dit kan als volgt worden benaderd:

PImage img = kinect2.getRegisteredImage()

tot slot kunt u voor kinect v1 (maar niet v2) ook de camerahoek aanpassen met de setTilt() methode.

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

zo, daar heb je het, hier zijn alle handige functies die u nodig zou kunnen hebben om de verwerking kinect bibliotheek te gebruiken:

  • initDevice() — begin van alles (video -, diepte -, IR)
  • activateDevice(int) – het activeren van een specifiek apparaat wanneer u meerdere apparaten aansluiten
  • initVideo() — start de video
  • enableIR(boolean) — aan-of uitschakelen van de IR-beeld van de camera (alleen v1)
  • initDepth() — start diepte
  • enableColorDepth(boolean) — aan-of uitschakelen van de diepte waarden als afbeelding in kleur
  • enableMirror(boolean) — spiegel de afbeelding en diepte gegevens (alleen v1)
  • PImage getVideoImage() — pak de RGB (of IR voor v1) op het videobeeld
  • PImage getIrImage() — pak het IR-beeld (v2 alleen)
  • PImage getDepthImage() — pak de diepte kaart afbeelding
  • PImage getRegisteredImage() — pak de geregistreerde diepteafbeelding (alleen v2))
  • int getRawDepth() — pak de ruwe dieptegegevens
  • float getTilt() — krijg de huidige sensor hoek (tussen 0 en 30 graden) (alleen v1)
  • setTilt(float) — pas de sensorhoek aan (tussen 0 en 30 graden) (alleen v1)

voor al het andere, kunt u ook een kijkje nemen op de javadoc referentie.

voorbeelden

er zijn vier basisvoorbeelden voor zowel v1 als v2.

RGB -, IR-en Diepteafbeeldingen

Code voor v1:RGBDepthTest

Code voor v2:RGBDepthTest2

dit voorbeeld gebruikt alle bovengenoemde functies om de gegevens van de kinect-sensor weer te geven.

meerdere apparaten

zowel v1 als v2 heeft meerdere kinect-ondersteuning.

Code voor v1: MultiKinect

Code voor v2:MultiKinect2

Point Cloud

Code voor v1: PointCloud

Code voor v2: PointCloud

Nummer één, we gebruiken de 3D mogelijkheden van verwerking om punten in de ruimte te tekenen. Je wilt jezelf vertrouwd maken met translate (), rotate (), pushMatrix (), popMatrix (). Deze tutorial is ook een goede plek om te beginnen. Daarnaast gebruikt het voorbeeld een PVector om een punt in 3D-ruimte te beschrijven. Meer hier: PVector tutorial.

het echte werk van dit voorbeeld komt echter helemaal niet van mij. De ruwe dieptewaarden van de kinect zijn niet direct evenredig met de fysieke diepte. Integendeel, ze schalen met de inverse van de diepte volgens deze formule:

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

in plaats van deze berekening altijd te doen, kunnen we al deze waarden vooraf berekenen in een lookup tabel omdat er slechts 2048 diepte waarden zijn.

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;}

met dank aan Matthew Fisher voor de bovenstaande formule. (OPMERKING: Om de resultaten nauwkeuriger te zijn, moet u uw specifieke kinect-apparaat kalibreren, maar de formule is dicht genoeg voor mij, dus ik blijf bij het voor nu. Meer over kalibratie in een moment.)

tenslotte kunnen we enkele punten tekenen op basis van de dieptewaarden in meters:

 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(); } }

gemiddeld punt Tracking

de echte magie van de kinect ligt in zijn computer vision mogelijkheden. Met diepteinformatie kun je allerlei leuke dingen doen, zoals zeggen: “de achtergrond is iets meer dan anderhalve meter. Negeer het!”Zonder diepte, achtergrond verwijdering omvat allerlei zorgvuldige pixel vergelijkingen. Als een snelle demonstratie van dit idee, hier is een zeer basic voorbeeld dat de gemiddelde XY locatie van elke pixels berekenen voor een bepaalde dieptedrempel.

Source for v1: AveragePointTracking

Source for v2: AveragePointTracking2

in dit voorbeeld verklaar ik twee variabelen om alle juiste x ‘en en y’ s op te tellen en één variabele om bij te houden hoeveel er zijn.

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

als we dan een bepaald punt vinden dat aan onze drempel voldoet, tel ik de x en y op bij de som.:

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

als we klaar zijn, berekenen we het gemiddelde en trekken een punt!

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

wat ontbreekt er?

  • alles wordt gevolgd via GitHub issues.

FAQ

  1. Wat zijn schaduwen in de diepteafbeelding (v1)? Kinect Schaduwdiagram
  2. Wat is het bereik van de diepte dat de kinect kan zien? (v1) ~ 0,7-6 meter of 2,3-20 voet. Merk op dat je zwarte pixels (of ruwe diepte waarde van 2048) krijgt bij beide elementen die te ver weg en te dichtbij zijn.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.