komma igång med Kinect och bearbetning

Microsoft Kinect-sensorn är en kringutrustning (designad för XBox-och windows-datorer) som fungerar ungefär som en webbkamera. Men förutom att tillhandahålla en RGB-bild ger den också en djupkarta. Betydelse för varje pixel som ses av sensorn, Kinect mäter avstånd från sensorn. Detta gör en mängd olika datorsynsproblem som bakgrundsavlägsnande, blobdetektering och enklare och roligare!

Kinect-sensorn mäter bara färg och djup. Men när den informationen finns på din dator kan mycket mer göras som ”skelett” – spårning (dvs. att upptäcka en modell av en person och spåra hans/hennes rörelser). För att göra skelettspårning måste du använda Thomas Lenglings Windows-Only Kinect v2-bearbetning libray. Men om du är på en Mac och allt du vill ha är rådata från Kinect, har du tur! Detta bibliotek använder libfreenect och libfreenect2 öppen källkod drivrutiner för att komma åt dessa data för Mac OS X (Windows-stöd kommer snart).

vilken hårdvara behöver jag?

först behöver du en” fristående ” kinect. Du behöver inte köpa en Xbox.

  • fristående Kinect Sensor v1. Jag tror att den här kommer med strömförsörjningen så att du inte behöver en separat adapter som listas nästa. Men om du har en kinect v1 som medföljde en XBox, kommer den inte att inkludera Kinect-sensorns strömförsörjning.
  • fristående Kinect Sensor v2. Du behöver förmodligen Kinect-adaptern för Windows. Inte kastas bort, även om det står windows, Detta gör att du kan ansluta den till din mac via USB. Slutligen vill du också se till att din dator stöder USB 3. De flesta moderna maskiner gör det, men om du är osäker kan du ta reda på mer här för Mac OS X.

några ytterligare anteckningar om olika modeller:

  • Kinect 1414: detta är den ursprungliga kinect och arbetar med biblioteket dokumenterat på denna sida i Processing 3.0 beta-serien.
  • Kinect 1473: detta ser identiskt ut med 1414, men är en uppdaterad modell. Det borde fungera med det här biblioteket, men jag har ingen att testa. Låt mig veta om det gör eller inte!
  • Kinect för Windows version 1:???? Hjälp? Fungerar den här?
  • Kinect för Windows version 2: Detta är varumärket spanking new kinect med alla funktioner som finns i XBox One Kinect. Fungerar även med detta bibliotek!

SimpleOpenNI

du kan också överväga att använda SimpleOpenNI-biblioteket och läsa Greg Borensteins Making Things See-bok. OpenNI har funktioner (skelettspårning, gestigenkänning etc.) som inte är tillgängliga i det här biblioteket. Tyvärr, OpenNI köptes nyligen av Apple och, medan jag trodde att det stängdes, verkar det finnas några ansträngningar för att återuppliva det!. Det är oklart vad framtiden kommer att bli av OpenNI och SimpleOpenNI.

jag är redo att komma igång just nu

det enklaste sättet att installera biblioteket är med Processing Contributions Manager Sketch Hawaiiiimportbibliotek, Lägg till bibliotek och Sök efter ”Kinect”. En knapp visas märkt”installera”.Om du vill installera den manuellt ladda ner den senaste versionen och extrahera den i mappen Bibliotek. Starta om bearbetningen, öppna ett av exemplen i mappen exempel och du är bra att gå!

Vad är bearbetning?

Processing är ett open source programmeringsspråk och miljö för människor som vill skapa bilder, animationer och interaktioner. Ursprungligen utvecklats för att fungera som en programvara skissbok och att lära grunderna i datorprogrammering inom ett visuellt sammanhang, bearbetning har också utvecklats till ett verktyg för att generera färdiga professionellt arbete. Idag finns det tiotusentals studenter, konstnärer, designers, forskare och hobbyister som använder bearbetning för lärande, prototyper och produktion.

vad händer om jag inte vill använda bearbetning?

om du är bekväm med C++ föreslår jag att du överväger att använda openFrameworks eller Cinder med Kinect. Dessa miljöer har några ytterligare funktioner och du kan också få en C++ – hastighetsfördel när du bearbetar djupdata etc.:

  • ofxKinect
  • Kinect CinderBlock
  • fler resurser från: OpenKinect-projektet

vilken kod skriver jag?

första är att inkludera rätt import uttalanden högst upp i din kod:

import org.openkinect.processing.*;

samt en hänvisning till ett Kinect objekt, dvs.

Kinect kinect;

sedan i setup() kan du initiera det kinect-objektet:

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

om du använder en Kinect v2, använd istället ett Kinect2-objekt.

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

när du har gjort detta kan du börja komma åt data från kinect-sensorn. För närvarande gör biblioteket data tillgängliga för dig på fem sätt:

  • PImage (RGB) från kinect-videokameran.
  • PImage (grayscale) från kinect IR-kameran.
  • PImage (grayscale) med varje Pixels ljusstyrka mappad till djup (ljusare = närmare).
  • PImage (RGB) med varje Pixels nyans mappad till djup.
  • int array med raw djupdata (11 bitars tal mellan 0 och 2048).

Låt oss titta på dessa i taget. Om du vill använda Kinect precis som en vanlig gammal webbkamera kan du komma åt videobilden som en PImage!

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

du kan helt enkelt be om den här bilden i draw(), men om du också kan använda videoEvent() för att veta när en ny bild är tillgänglig.

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

om du vill ha IR-bilden:

kinect.enableIR(true);

med kinect v1 kan inte få både videobilden och IR-bilden. De skickas båda tillbaka via getVideoImage () så vilken som senast var aktiverad är den du får. Men med Kinect v2 är de båda tillgängliga som separata metoder:

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

om du vill ha djupbilden kan du nu begära gråskalebilden:

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

liksom de råa djupdata:

int depth = kinect.getRawDepth();

för kinect v1 varierar rådjupvärdena mellan 0 och 2048, för kinect v2 är intervallet mellan 0 och 4500.

för färgdjupbilden, använd kinect.enableColorDepth(true);. Och precis som med videobilden finns det en djuphändelse som du kan komma åt om det behövs.

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

tyvärr, b / c RGB-kameran och IR-kameran är inte fysiskt placerade på samma plats, det finns ett stereosynproblem. Pixel XY i en bild är inte samma XY i en bild från en kamera en tum till höger. Kinect v2 erbjuder vad som kallas en” registrerad ” bild som justerar alla djupvärden med RGB-kameran. Detta kan nås enligt följande:

PImage img = kinect2.getRegisteredImage()

slutligen, för kinect v1 (men inte v2) kan du också justera kameravinkeln med setTilt() – metoden.

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

så där har du det, här är alla användbara funktioner Du kan behöva använda Kinect-biblioteket:

  • initDevice() — börja allt (video, djup, IR)
  • activateDevice(int) – aktivera en specifik enhet när flera enheter är anslutna
  • initVideo() — starta endast video
  • enableIR(boolean) — slå på eller av IR-kamerabilden (endast v1)
  • initDepth() — endast startdjup
  • enableColorDepth(boolean) — slå på eller av djupvärdena som färgbild
  • enableMirror(boolean) — spegla bild – och djupdata (endast v1)
  • PImage getVideoImage() — ta tag i RGB (eller IR för v1) videobild
  • PImage getIrImage() — ta tag i IR-bilden (endast v2)
  • PImage getDepthImage() — ta tag i djupkartan bild
  • PImage getRegisteredImage() — ta tag i den registrerade djupbilden (endast v2)
  • int getRawDepth() — ta tag i raw-djupdata
  • float getTilt() — få den aktuella sensorvinkeln (mellan 0 och 30 grader) (endast v1)
  • setTilt(float) — justera sensorvinkeln (mellan 0 och 30 grader) (endast v1)

för allt annat kan du också titta på javadoc-referensen.

exempel

det finns fyra grundläggande exempel för både v1 och v2.

Visa RGB -, IR-och Djupbilder

kod för v1: RGBDepthTest

kod för v2:RGBDepthTest2

i det här exemplet används alla ovanstående funktioner för att visa data från kinect-sensorn.

flera enheter

både v1 och v2 har flera kinect-stöd.

kod för v1:MultiKinect

kod för v2:MultiKinect2

punktmoln

kod för v1: PointCloud

kod för v2: PointCloud

här gör vi något lite snyggare. Nummer ett, vi använder 3D-funktionerna för bearbetning för att rita poäng i rymden. Du vill bekanta dig med translate(), rotate(), pushMatrix(), popMatrix(). Denna handledning är också ett bra ställe att börja. Dessutom använder exemplet en Pvektor för att beskriva en punkt i 3D-rymden. Mer här: pvector tutorial.

det verkliga arbetet med detta exempel kommer dock inte från mig alls. De råa djupvärdena från kinect är inte direkt proportionella mot fysiskt djup. Snarare skala de med invers av djupet enligt denna formel:

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

i stället för att göra denna beräkning hela tiden kan vi förberäkna alla dessa värden i en uppslagstabell eftersom det bara finns 2048 djupvärden.

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

tack till Matthew Fisher för ovanstående formel. För att resultaten ska bli mer exakta måste du kalibrera din specifika kinect-enhet, men formeln är tillräckligt nära för mig så jag håller fast vid det för tillfället. Mer om kalibrering på ett ögonblick.)

slutligen kan vi rita några punkter baserat på djupvärdena i meter:

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

Genomsnittlig Punktspårning

Kinects verkliga magi ligger i dess datorsynfunktioner. Med djupinformation kan du göra alla möjliga roliga saker som att säga: ”bakgrunden är allt bortom 5 fot. Ignorera det!”Utan djup innebär bakgrundsavlägsnande alla slags noggranna pixeljämförelser. Som en snabb demonstration av den här tanken är här ett mycket grundläggande exempel som beräknar den genomsnittliga XY-platsen för alla pixlar framför ett givet djuptröskel.

källa för v1: AveragePointTracking

källa för v2: AveragePointTracking2

i det här exemplet förklarar jag två variabler för att lägga till alla lämpliga x och y och en variabel för att hålla reda på hur många det finns.

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

sedan, när vi hittar en given punkt som överensstämmer med vår tröskel, lägger jag till x och y till summan:

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

när vi är klara beräknar vi genomsnittet och ritar en punkt!

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

vad saknas?

  • allt spåras via github-problem.

FAQ

  1. Vad finns det skuggor i djupbilden (v1)? Kinect Shadow diagram
  2. Vad är det djupområde som kinect kan se? (v1) ~0,7–6 meter eller 2,3–20 fot. Obs! du får svarta pixlar (eller raw djupvärde 2048) på båda elementen som är för långt borta och för nära.

Lämna ett svar

Din e-postadress kommer inte publiceras.