Visualizzazione post con etichetta Kinect. Mostra tutti i post
Visualizzazione post con etichetta Kinect. Mostra tutti i post

martedì 8 aprile 2014

Accuratezza del sensore di distanza di Kinect (2)




Per cercare di studiare un po' di piu' la precisione del Kinect ho effettuato due serie di misure a distanza fissa e una serie di misure a distanze progressive (misurate con stecca centimetrata)

Ad una distanza di  circa 60 cm (la distanza del kinect dal bersaglio e' approssimata in quanto non e' semplice misurare la reale distanza tra il sensore ed il bersaglio a meno di non smontare il dispositivo) e' emerso che da 436 misure la distanza media misurata e' stata di 602.1 mm con una standard deviation di +- 0.56 mm

Ad una distanza di  circa 73 cm  e' emerso che da 325 misure la distanza media misurata e' stata di 728.6 mm con una standard deviation di +- 0.52 mm

Le cose cambiano in modo sensibile se si punta un bersaglio fisso distante (maggiore di 2 m)
In questo caso, come si osserva nel grafico sottostante, su oltre 1100 misure, i dati si sono distribuiti in due grandi classi (2252 mm e 2206 mm). L'incertezza quindi sale a 5 cm






In seguito il bersaglio e' stato spostato su una stecca centimetrata da circa 60 a circa 73 cm di distanza (per evitare errori sono state considerate solo le distanze relative partendo dal punto di partenza)

i risultati sono buoni ma non eccezionali e comunque il linea  con quanto dichiarato a questo link

Range: ~ 50 cm to 5 m. Can get closer (~ 40 cm) in parts, but can't have the full view be < 50 cm.
Horizontal Resolution: 640 x 480 and 45 degrees vertical FOV and 58 degrees horizontal FOV. Simple geometry shows is about ~ 0.75 mm per pixel x by y at 50 cm, and ~ 3 mm per pixel x by y at 2 m.
Depth resolution: ~ 1.5 mm at 50 cm. About 5 cm at 5 m.

mercoledì 2 aprile 2014

Accuratezza del sensore di distanza di Kinect

Per verificare l'accuratezza del sensore di distanza del Kinect ho provato ad acquisire due immagini di una stessa scena statica e a vedere le differenze

Mappa di profondita' di Kinect

Le due immagini sono state acquisite con lo script visto in questo post

Per calcolare la differenza ho usato il seguente script
------------------------------------------------
import pickle
import numpy as np
import Image

posizione = 0
accumula = 0

f = open("3.txt")
data1 = pickle.load(f)
f.close

f = open("4.txt")
data = pickle.load(f)
f.close
accumula = data - data1

img = Image.new('L', (480,640), "black")
pixels = img.load()

for i in range(img.size[0]):
for j in range(img.size[1]):
pixels[i,j] = accumula[posizione]
posizione = posizione + 1

img2 = img.rotate(270)
img2.save("3-4.png")

print np.histogram(accumula,[-3000,-100,-10,10,100,3000])
------------------------------------------------

Questa e' l'immagine di differenza
E' subito evidente che le maggiori differenze sono ubicate nei punti in cui c'e' la maggior distanza tra due pixel vicini

Mappa delle differenze test 1


La distribuzione di frequenza indica che per il 92.6% la differenza di distanza misurata e' compresa tra -1/+1 cm. Un altro 5.7% delle differenze e' compresa tra -10/+10 cm
Per maggiore dettaglio il 75% delle misure ha differenza 0


Un altro esempio

Mappa delle differenze Test 2

in questo caso il 77% dei punti mostra differenza di 0 mm con il 93% dei punti con differenza inferiore a 1 cm.


Un terzo esempio

Mappa delle differenze Test 3

anche qui il 76% dei punti mostra differenza di 0 mm con il 92.4% dei punti con differenza inferiore a 1 cm.




In buona sostanza il sensore di Kinect lavora molto bene su scene piatte mentre dove ci sono oggetti su piani a distanza differente con bruschi salti di distanza l'errore diventa sensibile





Depth Map di Kinect con PyOpenNi e Meshlab

Su richiesta di un amico, ho provato ad usare il Kinect per fare un modello 3D del viso
Il lavoro e' diviso in due parti. In fase di acquisizione vengono salvati i dati del sensore di distanza del Kinect ogni 5 secondi (il Kinect genera una mappa di 640x480 punti per ogni immagini ed i dati acquisiti da PyOpenNi sono espressi direttamente in millimetri)



Successivamente si lancia lo script di lettura.py come

python lettura.py > dati.asc

il file .asc viene poi utilizzato dal programma Meshlab (presenti anche repository di Ubuntu) per visualizzare la nuvola dei punti. (Nell'esempio sono stati i punti a distanza maggiore di 1 metro per selezionare solo i punti del volto) 


acquisisci.py
-----------------------------------------------
import time
import pickle
import numpy as np
import Image
import scipy


ctx = Context()
ctx.init()

# Create a depth generator
depth = DepthGenerator()
depth.create(ctx)

# Set it to VGA maps at 30 FPS
depth.set_resolution_preset(RES_VGA)
depth.fps = 30

# Start generating
ctx.start_generating_all()

contatore =1
while True:
    # Update to next frame
    nRetVal = ctx.wait_one_update_all(depth)

    depthMap = depth.map
    depthMap2 = np.array(depthMap)
    f = open("faccia"+str(contatore)+".txt","w+b")
    pickle.dump(depthMap2,f)
    f.close()

    print contatore

    contatore = contatore + 1
    time.sleep(5)
-----------------------------------------------
lettura.py
-----------------------------------------------
import pickle
import numpy

posizione = 0

f = open("faccia5.txt")
data = pickle.load(f)
f.close

for i in range(img.size[0]):
for j in range(img.size[1]):
print str(i)+","+str(j)+","+str(data[posizione]) 
posizione = posizione + 1


venerdì 21 marzo 2014

Interazione tra Kinect ed XWindow con PyOpenNi

Francamente non amo Processing (a meno che non si declini come IDE di Arduino) ed dopo un po' di ricerche ho trovato il modo di pilotare Kinect mediante Python con la libreria PyOpenNi

L'installazione e' sostanzialmente manuale dai sorgenti con la procedura

git clone https://github.com/jmendeth/PyOpenNI.git 

mkdir PyOpenNI-build 
cd PyOpenNI-build 
cmake ../PyOpenNI
(per soddisfare le dipendenze sudo apt-get install cmake build-essential git-core \ python-dev libboost-python-dev)

Al termine della compilazione non c'e' la possibilita' di fare make install in  quanto e' lasciato all'utente la fase finale. Per i miei scopi la cosa piu' semplice e' stata quella di spostare il file openni.so dalla PyOpenNI-build/lib nella cartella degli esempi


Un esempio veramente interessate e' dato da hand-tracker.py che, brevemente modificato, puo' essere utilizzato per creare un mouse virtuale per X (nel brevissimo esempio se la mano si trova tra 750 e 1000 mm dal Kinect viene agganciato il Kinect, se si trova a meno di 750 mm si fa clic sul punto del mouse....lo script e' ampiamente migliorabile)

------------------------------------------------
#! /usr/bin/python

from openni import *
import os

context = Context()
context.init()

depth_generator = DepthGenerator()
depth_generator.create(context)
depth_generator.set_resolution_preset(RES_VGA)
depth_generator.fps = 30

gesture_generator = GestureGenerator()
gesture_generator.create(context)
gesture_generator.add_gesture('Wave')

hands_generator = HandsGenerator()
hands_generator.create(context)

# Declare the callbacks
# gesture
def gesture_detected(src, gesture, id, end_point):
    print "Detected gesture:", gesture
    hands_generator.start_tracking(end_point)
# gesture_detected

def gesture_progress(src, gesture, point, progress): pass
# gesture_progress

def create(src, id, pos, time):
    print 'Create ', id, pos
# create

def update(src, id, pos, time):
    print 'Update ', id, pos
    x = pos[0]+300
    y = pos[1]+300

    if (x < 0):
x = 0
 
    if (y < 0):
y = 0
    if ((pos[2] >750) and (pos[2] < 1000)):
os.system("xdotool mousemove "+ str(x)+" "+str(y))

    if (pos[2] <750):
os.system("xdotool mousemove "+ str(x)+" "+str(y) + " click 1")

# update

def destroy(src, id, time):
    print 'Destroy ', id
# destroy

# Register the callbacks
gesture_generator.register_gesture_cb(gesture_detected, gesture_progress)
hands_generator.register_hand_cb(create, update, destroy)

# Start generating
context.start_generating_all()

print 'Make a Wave to start tracking...'

while True:
    context.wait_any_update_all()
# while






giovedì 13 marzo 2014

Kinect su Ubuntu

Dopo il tentativo non perfettamente andato a buon fine descritto in questo post, sono tornato indietro sui mie passi per installare Kinect su un Ubuntu 12.04 32 Bit ed usando una versione piu' vecchiotta di Processing

I passi sono stati ripresi quasi totalmente da questo link

Si deve scaricare il pacchetto di OpenNi da questo link, si decomprime il pacchetto zip e poi, entrando in ognuna delle sottodirectory si lancia il file ./install.sh (ripeto per ogni sottodirectory)

A questo punto si installa Processing (attenzione versione 1.5) e si scarica la libreria SimpleOpenNi. Questa libreria deve essere decompressa ed inserita nella sottodirectory libraries di Processing (se non e' presente la sottodirectory si deve creare a mano)

Per terminare ho dovuto digitare i seguenti comandi
wget https://simple-openni.googlecode.com/svn/trunk/SimpleOpenNI-2.0/platform/linux/installLinuxRules.sh
wget https://simple-openni.googlecode.com/svn/trunk/SimpleOpenNI-2.0/platform/linux/primesense-usb.rules
sudo ./installLinuxRules.sh

Ovviamente se ci sono problemi di dipendenze delle librerie, questi devono essere risolti via via

A questo punto si puo' procedere lanciando gli esempi contenuti tra gli sketch di Processing

Hands3D Demo

Hands Demo


User3D Demo


User Demo

lunedì 10 febbraio 2014

Kinect su Debian


Grazie ad un amico che e' passato su XBoxOne ho potuto provare la vecchia versione di Kinect da XBox360.

Per interagire con il dispositivo si deve usare (su computer non Windows) la libreria OpenKinect che ho compilato dai sorgenti mediante i comandi

apt-get install cmake libglut3-dev pkg-config build-essential libxmu-dev libxi-dev libusb-1.0-0-dev

git clone https://github.com/OpenKinect/libfreenect.git 
cd libfreenect
mkdir build
cd build
cmake .. 
make
sudo make install
sudo ldconfig /usr/local/lib64/

per verificare che il tutto funzioni si puo' lanciare il comando glview



Il sistema funziona ma l'aspetto piu' interessante e' quello delle interpretazioni delle gesture in modo da rendere veramente interattivo il kinect.
La soluzione piu' semplice e' quella di usare Processing con la libreria Simple OpenNI (che si installa dall'interno di Processing con il menu Sketch->Import Library->Add Library. Esistono molti esempi in questo campo ed anche un libro (sull'interazione tra Kinect ed Arduino) ma con la versione 2 della libreria gli sketch non sembrano funzionare ed e' bene usare gli esempi legati alla libreria scaricata)





Funziona tutto tranne il fatto che viene mostrato questo errore

Listening for transport dt_socket at address: 8276
libEGL warning: failed to create a pipe screen for i965
Smooth is not supported by this hardware (or driver)

per questo motivo non e' possibile vedere il tracking delle mani nel video sottostante (esempio Hands3D)


Tour de France Firenze Gran Depart

  Poagcar Wout Van Aert Vingegaard       Van Der Poel