Noțiuni de bază cu Kinect și procesare

senzorul Microsoft Kinect este un dispozitiv periferic (conceput pentru PC-urile XBox și windows) care funcționează la fel ca o cameră web. Cu toate acestea, pe lângă furnizarea unei imagini RGB, oferă și o hartă de adâncime. Adică pentru fiecare pixel văzut de senzor, Kinect măsoară distanța față de senzor. Acest lucru face ca o varietate de probleme de vedere de calculator, cum ar fi îndepărtarea de fundal, detectarea blob, și mai ușor și distractiv!

senzorul Kinect în sine măsoară doar culoarea și adâncimea. Cu toate acestea, odată ce aceste informații se află pe computerul dvs., se pot face multe altele, cum ar fi urmărirea „scheletului” (adică detectarea unui model al unei persoane și urmărirea mișcărilor sale). Pentru a face urmărirea scheletului, va trebui să utilizați Windows-ul lui Thomas Lengling Kinect v2 processing libray. Cu toate acestea, dacă sunteți pe un Mac și tot ce doriți sunt date brute de la Kinect, aveți noroc! Această bibliotecă utilizează libfreenect și libfreenect2 drivere open source pentru a accesa aceste date pentru Mac OS X (Suport pentru windows în curând).

ce hardware am nevoie?

mai întâi aveți nevoie de un kinect „autonom”. Nu trebuie să cumpărați un Xbox.

  • senzor Kinect autonom v1. Cred că acesta vine cu sursa de alimentare, astfel încât să nu aveți nevoie de un adaptor separat listat în continuare. Cu toate acestea, dacă aveți un kinect v1 care a venit cu un XBox, acesta nu va include sursa de alimentare a senzorului Kinect.
  • senzor Kinect independent v2. De asemenea, probabil că aveți nevoie de adaptorul Kinect pentru Windows. Nu vă lăsați aruncați, deși spune windows, acest lucru vă va permite să îl conectați la mac prin USB. În cele din urmă, veți dori, de asemenea, să vă asigurați că computerul dvs. acceptă USB 3. Majoritatea mașinilor moderne o fac, dar dacă nu sunteți sigur, puteți afla mai multe aici pentru Mac OS X.

câteva note suplimentare despre diferite modele:

  • Kinect 1414: acesta este kinect original și funcționează cu Biblioteca documentată pe această pagină în seria Processing 3.0 beta.
  • Kinect 1473: acesta arată identic cu 1414, dar este un model actualizat. Ar trebui să funcționeze cu această bibliotecă, dar nu am una de testat. Vă rog să-mi spuneți dacă o face sau nu!
  • Kinect pentru Windows versiunea 1: ???? Ajutor? Asta funcționează?
  • Kinect pentru Windows versiunea 2: Acesta este noul kinect cu toate caracteristicile găsite în XBox One Kinect. De asemenea, funcționează cu această bibliotecă!

SimpleOpenNI

de asemenea, puteți lua în considerare utilizarea bibliotecii SimpleOpenNI și citiți cartea lui Greg Borenstein Making Things See. OpenNI are caracteristici (urmărirea scheletului, recunoașterea gesturilor etc.) care nu sunt disponibile în această bibliotecă. Din păcate, OpenNI a fost achiziționat recent de Apple și, în timp ce am crezut că a fost închis, acolo jos par să existe unele eforturi pentru a-l reînvia!. Nu este clar care va fi viitorul OpenNI și SimpleOpenNI.

sunt gata să încep chiar acum

cel mai simplu mod de a instala biblioteca este cu managerul de contribuții de procesare Sketch bibliotecile de Import de import de la XV adăugați biblioteca și căutați „Kinect”. Va apărea un buton etichetat”instalare”.Dacă doriți să o instalați manual, descărcați cea mai recentă versiune și extrageți-o în folderul biblioteci. Reporniți procesarea, deschideți unul dintre exemplele din folderul exemple și sunteți bine să mergeți!

ce este procesarea?

procesarea este un limbaj de programare open source și un mediu pentru persoanele care doresc să creeze imagini, animații și interacțiuni. Dezvoltat inițial pentru a servi ca un caiet de schițe software și pentru a preda fundamentele programării computerului într-un context vizual, procesarea a evoluat, de asemenea, într-un instrument pentru generarea lucrărilor profesionale terminate. Astăzi, există zeci de mii de studenți, artiști, designeri, cercetători și pasionați care folosesc procesarea pentru învățare, prototipare și producție.

ce se întâmplă dacă nu vreau să folosesc procesarea?

dacă sunteți confortabil cu C++ vă sugerez să luați în considerare utilizarea openFrameworks sau Cinder cu Kinect. Aceste medii au unele caracteristici suplimentare și, de asemenea, puteți obține un avantaj de viteză C++ atunci când prelucrați datele de adâncime etc.:

  • ofxKinect
  • Kinect CinderBlock
  • mai multe resurse de la: proiectul OpenKinect

ce Cod scriu?

primul lucru este să includeți declarațiile de import corespunzătoare în partea de sus a codului:

import org.openkinect.processing.*;

precum și o referință la un obiect Kinect, adică.

Kinect kinect;

apoi, în setup() puteți inițializa acel obiect kinect:

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

dacă utilizați un Kinect V2, utilizați în schimb un obiect Kinect2.

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

după ce ați făcut acest lucru, puteți începe să accesați datele de la senzorul kinect. În prezent, biblioteca vă pune la dispoziție date în cinci moduri:

  • PImage (RGB) de la camera video kinect.
  • PImage (grayscale) de la camera Kinect IR.
  • PImage (grayscale) cu luminozitatea fiecărui pixel mapată la adâncime (brighter = closer).
  • PImage (RGB) cu nuanța fiecărui pixel mapată la adâncime.
  • int array cu date de adâncime brute (numere de 11 biți între 0 și 2048).

să ne uităm la acestea pe rând. Dacă doriți să utilizați Kinect la fel ca o cameră web veche obișnuită, puteți accesa imaginea video ca PImage!

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

puteți cere pur și simplu această imagine în draw(), totuși, dacă puteți utiliza și videoEvent() pentru a ști când este disponibilă o nouă imagine.

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

dacă doriți imaginea IR:

kinect.enableIR(true);

cu kinect v1 nu se poate obține atât imaginea video, cât și imaginea IR. Ambele sunt transmise înapoi prin getVideoImage (), astfel încât oricare dintre acestea a fost activat cel mai recent este cel pe care îl veți obține. Cu toate acestea, cu Kinect v2, ambele sunt disponibile ca metode separate:

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

acum, dacă doriți imaginea de adâncime, puteți solicita imaginea în tonuri de gri:

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

precum și datele de adâncime brute:

int depth = kinect.getRawDepth();

pentru kinect v1, valorile adâncimii brute variază între 0 și 2048, pentru kinect v2 intervalul este cuprins între 0 și 4500.

pentru imaginea color depth, utilizați kinect.enableColorDepth(true);. Și la fel ca în cazul imaginii video, există un eveniment de adâncime pe care îl puteți accesa dacă este necesar.

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

din păcate, b / C camera RGB și camera IR nu sunt amplasate fizic în același loc, există o problemă de vedere stereo. Pixel XY într-o singură imagine nu este același XY într-o imagine dintr-o cameră la un centimetru spre dreapta. Kinect v2 oferă ceea ce se numește o imagine „înregistrată” care aliniază toate valorile de adâncime cu cele ale camerei RGB. Acest lucru poate fi accesat după cum urmează:

PImage img = kinect2.getRegisteredImage()

în cele din urmă, pentru kinect v1 (dar nu v2), puteți regla și unghiul camerei cu metoda setTilt().

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

Deci, acolo aveți, aici sunt toate funcțiile utile de care aveți nevoie pentru a utiliza biblioteca Processing kinect:

  • initDevice() — începeți totul (video, adâncime, IR)
  • activateDevice(int) – activați un anumit dispozitiv atunci când se conectează mai multe dispozitive
  • initVideo() — porniți numai videoclipul
  • enableIR(boolean) — activați sau dezactivați imaginea camerei IR (numai v1)
  • initDepth() — numai adâncimea de pornire
  • enableColorDepth(boolean) — activați sau dezactivați valorile adâncimii ca imagine color
  • enableMirror(boolean) — oglindiți imaginea și datele de adâncime (numai v1)
  • PImage getVideoImage() — apuca RGB (sau IR pentru v1) imagine video
  • PImage getIrImage() — apuca imaginea IR (numai v2)
  • PImage getDepthImage() — apuca harta adâncime imagine
  • PImage getRegisteredImage() — prinde imaginea de adâncime înregistrată (numai v2)
  • int getRawDepth() — prinde datele de adâncime brute
  • float getTilt() — obțineți unghiul senzorului curent (între 0 și 30 de grade) (numai v1)
  • setTilt(float) — reglați unghiul senzorului (între 0 și 30 de grade) (numai v1)

pentru orice altceva, puteți arunca o privire și la referința javadoc.

Exemple

există patru exemple de bază atât pentru v1, cât și pentru v2.

Afișează imagini RGB, IR și adâncime

cod pentru v1: RGBDepthTest

cod pentru V2:RGBDepthTest2

acest exemplu utilizează toate funcțiile enumerate mai sus pentru a afișa datele de la senzorul kinect.

mai multe dispozitive

atât v1 cât și v2 au suport kinect multiplu.

cod pentru v1: MultiKinect

cod pentru v2:MultiKinect2

punct Cloud

cod pentru v1: PointCloud

cod pentru V2: PointCloud

aici, facem ceva un pic crescator. Numărul unu, folosim capacitățile 3D de procesare pentru a atrage puncte în spațiu. Veți dori să vă familiarizați cu translate(), rotate(), pushMatrix(), popMatrix(). Acest tutorial este, de asemenea, un loc bun pentru a începe. În plus, exemplul folosește un PVector pentru a descrie un punct din spațiul 3D. Mai multe aici: tutorial PVector.

lucrarea reală a acestui exemplu, totuși, nu vine deloc de la mine. Valorile adâncimii brute din kinect nu sunt direct proporționale cu adâncimea fizică. Mai degrabă, ele se scalează cu inversul adâncimii conform acestei formule:

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

în loc să facem acest calcul tot timpul, putem precomputa toate aceste valori într-un tabel de căutare, deoarece există doar 2048 valori de adâncime.

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

mulțumesc lui Matthew Fisher pentru formula de mai sus. (Notă: pentru ca rezultatele să fie mai precise, va trebui să calibrați dispozitivul kinect specific, dar formula este suficient de aproape pentru mine, așa că rămân cu ea deocamdată. Mai multe despre calibrare într-o clipă.)

în cele din urmă, putem desena câteva puncte pe baza valorilor adâncimii în metri:

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

urmărirea medie a punctelor

magia reală a kinect constă în capacitățile sale de viziune pe computer. Cu informații de profunzime, puteți face tot felul de lucruri distractive, cum ar fi să spuneți: „fundalul este ceva dincolo de 5 picioare. Ignoră-l!”Fără profunzime, îndepărtarea fundalului implică tot felul de comparații minuțioase ale pixelilor. Ca o demonstrație rapidă a acestei idei, Aici este un exemplu foarte de bază care calculează locația medie xy a oricăror pixeli în fața unui prag de adâncime dat.

sursa pentru v1: AveragePointTracking

sursa pentru v2: AveragePointTracking2

în acest exemplu, declar două variabile pentru a adăuga toate X și y corespunzătoare și o variabilă pentru a urmări cât de multe sunt.

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

apoi, ori de câte ori găsim un punct dat care respectă pragul nostru, adaug x și y La sumă:

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

când am terminat, calculăm media și tragem un punct!

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

ce lipsește?

  • totul este urmărit prin probleme github.

FAQ

  1. ce există umbre în imaginea de adâncime (v1)? Diagrama umbrelor Kinect
  2. care este intervalul de adâncime pe care kinect îl poate vedea? (v1) ~0.7–6 metri sau 2.3–20 picioare. Notă veți obține pixeli negri (sau valoarea adâncimii brute de 2048) la ambele elemente care sunt prea departe și prea aproape.

Lasă un răspuns

Adresa ta de email nu va fi publicată.