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
A seguito del precedente post, nell'utilizzo sono emersi un po' di problemi che hanno fatto ripensare all'utilizzo di Raspberry come Torrent Box
Il problema principale e' rappresentato dalle dimensioni del disco su cui salvare i dati. La soluzione piu' idonea e' quella di tenere i dati scaricati su una chiave (od un disco esterno) Usb mentre sulla SD Card rimane caricato il solo sistema operativo
L'altro problema e' come al solito l'utente (od utonto). L'amico per cui avevo preparato la Raspberry non vuole complicazione e vuole vedere i file dal suo portatile Windows (non si parla nemmeno di SFtp o simili) per cui e' necessario implementare un server Samba
Per il passo 1 si deve fare in modo che la chiave si monti sempre allo stesso modo.
Per fare cio' prima si trova l'UID della chiavetta con
ls -l /dev/disk/by-uuid/
e ci si segna il codice. Poi si crea la directory di mount
sudo mkdir /media/usb sudo chmod 775 /media/usb
al termine si modifica il file /etc/fstab aggiungendo la riga (mettendo il giusto UID prima salvato)
UUID=1111-2222 /media/usb vfat rw,defaults 0 0
per permettere al demone di scrivere sulla chiave Usb (che e' formattata Fat e quindi con una gestione un po' casinosa dei permessi) la via piu' semplice e' modificare il file /etc/init.d/transmission-daemon cambiando
USER=root(altrimenti si genera un errore Error: Permission denied (/media/ dopo un po' che si e' avviato il torrent)
a questo punto si modifica il file /etc/transmission-daemon/settings.json e si modificano le due voci per puntare alla posizione della chiave Usb
Per il passo 2 l'installazione del server Samba e' semplice sudo apt-get install samba samba-common-bin
a questo punto c'e' da configurare il file /etc/samba/smb.conf
si cambia quindi security=share
per semplicita' il disco Usb verra' visto con un accesso Guest su directory pubblica aggiungendo al termine del file [Guest]
comment = Guest access
share
path = /path/to/dir/to/share
browseable = yes
read only = yes
guest ok = yes
il fatto che i file siano a sola lettura da Windows non e' un problema perche' eventuali cancellazioni di torrent si effetturano direttamente dall'interfaccia di daemon-transmission
Al termine e' sufficiente collegarsi via browser all'indirizzo della Raspberry sulla porta 9091 per poter iniziare il download. Da Windows la condivisione sara' all'indirizzo //raspberry/Guest
Un amico mi ha chiesto se era possibile sviluppare una piccola applicazione interattiva per il museo di Scienze Geologiche del Dipartimento di Scienze della Terra di Firenze
L'idea di base era quella di usare Kinect per cambiare la slide ad una presentazione a video
L'idea mi sembrava carina ma piuttosto costosa in quanto necessita di un Kinect e di un computer discretamente potente per fare processare i dati (Kinect di suo non interpreta le gesture, e' solo un insieme di sensori)..volevo vedere se era possibile fare la stessa cosa usando solo una Raspberry ed una normale Webcam
L'idea di base e' stata rubata a questo sito semplificando di molto per cio' che non mi occorre. In pratica sull'immagine della Webcam sono state create due aree sensibili (i due cerchietti in alto, per essere precisi vengono letti solo due pixel), se l'utente passa la mano sui cerchietti (o meglio se viene individuata una variazione dell'immagine in corrispondenza dei pixel sensibili) viene generato un evento.
Per evitare falsi allarmi e' stato impostato una distanza minima di 1.5 secondi tra due eventi
Il programma processa i dati della webcam, crea una immagine differenza tra le immagini in sequenza e crea una immagine maschera dei pixel che risultano cambiati (si puo' vedere premendo il tasto d durante l'esecuzione). La condizione di pixel non cambiato e' 0, la condizione di cambiato e' 255
Se viene generato un evento allora mediante il programma xdotool viene inviato un segnale Freccia Destra/ Freccia Sinistra alla finestra che ha per nome "'presentazione.odp - LibreOffice Impress"
Ovviamente ci sono dei limiti all'utilizzo (del tipo la webcam non deve essere orientata verso il corridoio del museo altrimenti vengono generati eventi ogni volta che passa una persona) ma considerando il costo dell'applicazione e le possibili applicazioni (si puo' fare per esempio un quiz interattivo per bambini) direi che e' abbastanza interessante
----------------------------------------------------------------------------- #!/usr/bin/env python import cv import time from scipy import * from scipy.cluster import vq import numpy import sys, os, random#, hashlib from math import * class Target: def __init__(self): if len( sys.argv ) > 1: self.writer = None self.capture = cv.CaptureFromFile( sys.argv[1] ) frame = cv.QueryFrame(self.capture) frame_size = cv.GetSize(frame) else: fps=15 is_color = True self.capture = cv.CaptureFromCAM(0) cv.SetCaptureProperty( self.capture, cv.CV_CAP_PROP_FRAME_WIDTH, 640 ); cv.SetCaptureProperty( self.capture, cv.CV_CAP_PROP_FRAME_HEIGHT, 480 ); frame = cv.QueryFrame(self.capture) frame_size = cv.GetSize(frame) self.writer = None frame = cv.QueryFrame(self.capture) cv.NamedWindow("Museo", 1) def run(self): frame = cv.QueryFrame( self.capture ) frame_size = cv.GetSize( frame ) contatore = 0 tempo_d = 0 tempo_s = 0 # Capture the first frame from webcam for image properties display_image = cv.QueryFrame( self.capture ) # Greyscale image, thresholded to create the motion mask: grey_image = cv.CreateImage( cv.GetSize(frame), cv.IPL_DEPTH_8U, 1 ) # The RunningAvg() function requires a 32-bit or 64-bit image... running_average_image = cv.CreateImage( cv.GetSize(frame), cv.IPL_DEPTH_32F, 3 ) # ...but the AbsDiff() function requires matching image depths: running_average_in_display_color_depth = cv.CloneImage( display_image ) # The difference between the running average and the current frame: difference = cv.CloneImage( display_image ) #t0 = time.time() # For toggling display: image_list = [ "camera", "difference", "threshold"] image_index = 0 # Index into image_list # Prep for text drawing: text_font = cv.InitFont(cv.CV_FONT_HERSHEY_COMPLEX, .5, .5, 0.0, 1, cv.CV_AA ) while True: # Capture frame from webcam camera_image = cv.QueryFrame( self.capture ) frame_t0 = time.time() # Create an image with interactive feedback: display_image = cv.CloneImage( camera_image ) # Create a working "color image" to modify / blur color_image = cv.CloneImage( display_image ) # Smooth to get rid of false positives cv.Smooth( color_image, color_image, cv.CV_GAUSSIAN, 19, 0 ) # Use the Running Average as the static background # a = 0.020 leaves artifacts lingering way too long. # a = 0.320 works well at 320x240, 15fps. (1/a is roughly num frames.) cv.RunningAvg( color_image, running_average_image, 0.320, None ) # Convert the scale of the moving average. cv.ConvertScale( running_average_image, running_average_in_display_color_depth, 1.0, 0.0 ) # Subtract the current frame from the moving average. cv.AbsDiff( color_image, running_average_in_display_color_depth, difference ) # Convert the image to greyscale. cv.CvtColor( difference, grey_image, cv.CV_RGB2GRAY ) # Threshold the image to a black and white motion mask: cv.Threshold( grey_image, grey_image, 2, 255, cv.CV_THRESH_BINARY ) # Smooth and threshold again to eliminate "sparkles" cv.Smooth( grey_image, grey_image, cv.CV_GAUSSIAN, 19, 0 ) cv.Threshold( grey_image, grey_image, 240, 255, cv.CV_THRESH_BINARY ) grey_image_as_array = numpy.asarray( cv.GetMat( grey_image ) ) c = cv.WaitKey(7) % 0x100 if c == 27 or c == 10: break # Toggle which image to show if chr(c) == 'd': image_index = ( image_index + 1 ) % len( image_list ) image_name = image_list[ image_index ] # Display frame to user if image_name == "camera": image = camera_image cv.PutText( image, "O", (50,50), text_font, cv.CV_RGB(255,0,0) ) cv.PutText( image, "O", (590,50), text_font, cv.CV_RGB(0,255,0) ) elif image_name == "difference": image = difference cv.PutText( image, "O", (50,50), text_font, cv.CV_RGB(255,0,0) ) cv.PutText( image, "O", (590,50), text_font, cv.CV_RGB(0,255,0) ) elif image_name == "threshold": # Convert the image to color. cv.CvtColor( grey_image, display_image, cv.CV_GRAY2RGB ) image = display_image # Re-use display image here cv.PutText( image, "O", (50,50), text_font, cv.CV_RGB(255,0,0) ) cv.PutText( image, "O", (590,50), text_font, cv.CV_RGB(0,255,0) ) cv.PutText( image, str(contatore), (320,50), text_font, cv.CV_RGB(0,0,255) ) cv.ShowImage( "Museo", image ) #print grey_image_as_array.item((50,50)) if ((grey_image_as_array.item(50,50) == 255) and ((time.time()-tempo_d) > 1.5)): #print time.time()-tempo_d tempo_d = time.time() contatore = contatore + 1 #print "destra" os.system("xdotool key --window $(xdotool search --name 'presentazione.odp - LibreOffice Impress') Left") if ((grey_image_as_array.item(50,590) == 255) and ((time.time()-tempo_s) > 1.5)): #print time.time()-tempo_s tempo_s = time.time() contatore = contatore - 1 #print "sinistra" os.system("xdotool key --window $(xdotool search --name 'presentazione.odp - LibreOffice Impress') Right") if self.writer: cv.WriteFrame( self.writer, image ); if __name__=="__main__": t = Target() t.run()
In questa prova viene presentato un semplice software per interagire con il Desktop grafico direttamente da script
il programma si chiama xdotool
con questo semplice script in Python per esempio si fa disegnare un cerchio sullo schermo al cursore del mouse (attenzione che si perde il controllo del mouse, per bloccare lo script si deve agire da tastiera)
-------------------------------------------------------------- import os,math angolo = 0.0 while 1: angolo = angolo+0.01 os.system("xdotool mousemove "+str((math.cos(angolo)*100)+300)+" " str((math.sin(angolo)*100)+300))
Sono sempre stato curioso di provare i dispositivi E-Ink come il Kindle e quando ho visto che la mia biblioteca ne dava alcuni in prestito (come se fossero libri) ho noleggiato il PocketBook Basic Touch della IBS
Si tratta di un dispositivo da 6 pollici a 16 livelli di grigio 800x600 con 4 Gb di memoria (espandibile da SD Card) che ha un costo di circa 75 euro
Le impressioni di uso sono abbastanza scoraggianti.
Ad esclusione della plastica del case, di qualita' non eccelsa, la cosa piu' fastidiosa e' il refresh dello schermo E-Ink. Come si puo' vedere dal mini video sottostante lo scroll e' tutto fuorche' fluido e lo schermo diventa in negativo ad ogni azione
Per confronto ho effettuato le stesse operazioni con il medesimo pdf sul Nexus 7 2012 usando MoonReader e l'usabilita' e' decisamente differente
Certo che i consumi di un ebook reader sono ridicoli rispetto ad un vero tablet
ma mi risulta difficile pensare a cosa possa servire un browser ed un visualizzatore di foto su uno schermo a 16 colori
In conclusione la chicca. Sono andato a letto e volevo leggere un po'...niente retroilluminazione. Il modello con retroilluminazione costa 125 euro. A questo punto la partita, anche economica, e' vinta dai tablet
Recentemente e' uscita una pagina intera su Repubblica ed un servizio al TG sul progetto Keepod,finanziato tramite IndieGoGo, con l'obbiettivo di garantire l'accesso al Personal Computing a quel 70% della popolazione mondiale che adesso non puo' permetterselo.
Progetto con finalita' sicuramente nobili che richiedeva un finanziamento di 38.000 dollari per creare un sistema operativo leggero e sicuro su chiave USB da affidare a ciascuna persona compresa nel progetto.
Al di la' della pagina intera di Repubblica la cosa mi sembrava di averla gia' vista diverse volte e di averla anche usata ed alla fine mi e' venuto in mente il progetto Tails, una distribuzione Linux avviabile da chiave USB fortemente orientata alla privacy con protezione sia del traffico dati che dei dati sulla penna USB
A cosa servono quindi i 38.000 dollari??? A sviluppare il sistema ?? Direi di no in quanto ci sono molte soluzioni gia' funzionanti oltre allo stesso Tail. A comprare il solo supporto fisico,ovvero la chiavetta, e a finanziare il costo di spedizione ??? Non c'e' traccia di cio' nel sito.
Mi sa che il progetto OLPC, anche se decisamente piu' ambizioso, era decisamente piu' trasparente
Per ottenere un client SSH su Mac Os X si puo', una volta aperto Terminale, andare nel menu Shell ed creare Nuova Connessione Remota dove impostare i parametri del server SSH
altrimenti rimane sempre valido da shell di Terminale digitare