Skip to content

Commit

Permalink
Added back optional numpy module loading for ptone : )
Browse files Browse the repository at this point in the history
Initial cython commit
readme
Changed all python library names to the new convention

Signed-off-by: Brandyn A. White <[email protected]>

Fixed a typo
Signed-off-by: Brandyn A. White <[email protected]>

Removed headers.  Made the setup look for them.
Signed-off-by: Brandyn A. White <[email protected]>

Updated readme with new path

Added -fPIC
Signed-off-by: Brandyn A. White <[email protected]>

Changed to use the shared libary, added help text
Signed-off-by: Brandyn A. White <[email protected]>

Added a new include path that is the default for OS x
Signed-off-by: Brandyn A. White <[email protected]>

Back to static (dynamic worked but it will be annoying for devs)
Signed-off-by: Brandyn A. White <[email protected]>

Added another include search path for OSX
Signed-off-by: Brandyn A. White <[email protected]>
  • Loading branch information
Brandyn A. White committed Nov 23, 2010
1 parent 2d9dcd0 commit c8613d9
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 103 deletions.
3 changes: 2 additions & 1 deletion README.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ currently consists of:
patches in platform directory) - GPL'd
- JoshBlake's C# OpenKinect (in the csharp directory, with inf files
in platform directory) - Apache'd
- Brandyn's Python bindings (in c/python, see README there)
- Brandyn's Python bindings (Ctypes/Cython + Sync/Async)
in libfreenect/python. (see README there)

The aggregated READMEs are below.

Expand Down
9 changes: 9 additions & 0 deletions python/cython/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
B1;2600;0cBrandyn White
[email protected]

**This is not completed yet, so if you are looking at it keep that in mind**

To compile you need to copy libfreenect.a to this directory, then run the demo in this directory. Nothing else has been tested. The header files are in here for simplicity, when this is integrated with the build system they will be accessed directly.

Build with (goes in this directory)
python setup.py build_ext --inplace
17 changes: 17 additions & 0 deletions python/cython/demo_cv_depth_show.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import freenect
import cv
import numpy as np

cv.NamedWindow('Depth')

def display(dev, data, timestamp):
data -= np.min(data.ravel())
data *= 65536 / np.max(data.ravel())
image = cv.CreateImageHeader((data.shape[1], data.shape[0]),
cv.IPL_DEPTH_16U,
1)
cv.SetData(image, data.tostring(),
data.dtype.itemsize * data.shape[1])
cv.ShowImage('Depth', image)
cv.WaitKey(5)
freenect.runloop(lambda *x: display(*freenect.depth_cb_np(*x)))
204 changes: 204 additions & 0 deletions python/cython/freenect.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import cython

FORMAT_RGB = 0
FORMAT_BAYER = 1
FORMAT_11_BIT = 0
FORMAT_10_BIT = 1
LED_OFF = 0
LED_GREEN = 1
LED_RED = 2
LED_YELLOW = 3
LED_BLINK_YELLOW = 4
LED_BLINK_GREEN = 5
LED_BLINK_RED_YELLOW = 6

cdef extern from "Python.h":
object PyString_FromStringAndSize(char *s, Py_ssize_t len)

cdef extern from "libfreenect.h":
ctypedef void (*freenect_depth_cb)(void *dev, char *depth, int timestamp) # was u_int32
ctypedef void (*freenect_rgb_cb)(void *dev, char *rgb, int timestamp) # was u_int32
int freenect_init(void **ctx, int usb_ctx) # changed from void * as usb_ctx is always NULL
int freenect_shutdown(void *ctx)
int freenect_process_events(void *ctx)
int freenect_num_devices(void *ctx)
int freenect_open_device(void *ctx, void **dev, int index)
int freenect_close_device(void *dev)
#void freenect_set_user(void *dev, void *user)
#void *freenect_get_user(void *dev)
void freenect_set_depth_callback(void *dev, freenect_depth_cb cb)
void freenect_set_rgb_callback(void *dev, freenect_rgb_cb cb)
int freenect_set_rgb_format(void *dev, int fmt)
int freenect_set_depth_format(void *dev, int fmt)
int freenect_start_depth(void *dev)
int freenect_start_rgb(void *dev)
int freenect_stop_depth(void *dev)
int freenect_stop_rgb(void *dev)
int freenect_set_tilt_degs(void *dev, double angle)
int freenect_set_led(void *dev, int option)
int freenect_get_raw_accel(void *dev, short int* x, short int* y, short int* z) # had to make these short int
int freenect_get_mks_accel(void *dev, double* x, double* y, double* z)


cdef class DevPtr:
cdef void* _ptr
def __repr__(self):
return "<Dev Pointer>"

cdef class CtxPtr:
cdef void* _ptr
def __repr__(self):
return "<Ctx Pointer>"

def set_rgb_format(DevPtr dev, int fmt):
return freenect_set_rgb_format(dev._ptr, fmt)

def set_depth_format(DevPtr dev, int fmt):
return freenect_set_depth_format(dev._ptr, fmt)

def start_depth(DevPtr dev):
return freenect_start_depth(dev._ptr)

def start_rgb(DevPtr dev):
return freenect_start_rgb(dev._ptr)

def stop_depth(DevPtr dev):
return freenect_stop_depth(dev._ptr)

def stop_rgb(DevPtr dev):
return freenect_stop_rgb(dev._ptr)

def shutdown(CtxPtr ctx):
return freenect_shutdown(ctx._ptr)

def process_events(CtxPtr ctx):
return freenect_process_events(ctx._ptr)

def num_devices(CtxPtr ctx):
return freenect_num_devices(ctx._ptr)

def close_device(DevPtr dev):
return freenect_close_device(dev._ptr)

def set_tilt_degs(DevPtr dev, float angle):
freenect_set_tilt_degs(dev._ptr, angle)

def set_led(DevPtr dev, int option):
return freenect_set_led(dev._ptr, option)

cdef init():
cdef void* ctx
if freenect_init(cython.address(ctx), 0) < 0:
print('Error: Cant open')
cdef CtxPtr ctx_out
ctx_out = CtxPtr()
ctx_out._ptr = ctx
return ctx_out

cdef open_device(CtxPtr ctx, int index):
cdef void* dev
if freenect_open_device(ctx._ptr, cython.address(dev), index) < 0:
print('Error: Cant open')
cdef DevPtr dev_out
dev_out = DevPtr()
dev_out._ptr = dev
return dev_out

_depth_cb, _rgb_cb = None, None

cdef void depth_cb(void *dev, char *data, int timestamp):
nbytes = 614400 # 480 * 640 * 2
cdef DevPtr dev_out
dev_out = DevPtr()
dev_out._ptr = dev
print(timestamp)
if _depth_cb:
_depth_cb(dev_out, PyString_FromStringAndSize(data, nbytes), timestamp)


cdef void rgb_cb(void *dev, char *data, int timestamp):
nbytes = 921600 # 480 * 640 * 3
cdef DevPtr dev_out
dev_out = DevPtr()
dev_out._ptr = dev
print(timestamp)
if _rgb_cb:
_rgb_cb(dev_out, PyString_FromStringAndSize(data, nbytes), timestamp)


def runloop(depth=None, rgb=None):
"""Sets up the kinect and maintains a runloop
This is where most of the action happens. You can get the dev pointer from the callback
and let this function do all of the setup for you. You may want to use threads to perform
computation externally as the callbacks should really just be used for copying data.
Args:
depth: A function that takes (dev, depth, timestamp), corresponding to C function.
If None (default), then you won't get a callback for depth.
rgb: A function that takes (dev, rgb, timestamp), corresponding to C function.
If None (default), then you won't get a callback for rgb.
"""
global _depth_cb, _rgb_cb
if depth:
_depth_cb = depth
if rgb:
_rgb_cb = rgb
cdef DevPtr dev
cdef CtxPtr ctx
cdef void* devp
cdef void* ctxp
ctx = init()
dev = open_device(ctx, 0)
devp = dev._ptr
ctxp = ctx._ptr
freenect_set_depth_format(devp, 0)
freenect_start_depth(devp)
freenect_set_rgb_format(devp, FORMAT_RGB)
freenect_start_rgb(devp)
freenect_set_depth_callback(devp, depth_cb)
freenect_set_rgb_callback(devp, rgb_cb)
while freenect_process_events(ctxp) >= 0:
pass

def _load_numpy():
try:
import numpy as np
return np
except ImportError, e:
print('You need the numpy library to use this function')
raise e


def depth_cb_np(dev, string, timestamp):
"""Converts the raw depth data into a numpy array for your function
Args:
dev: DevPtr object
string: A python string with the depth data
timestamp: An int representing the time
Returns:
(dev, data, timestamp) where data is a 2D numpy array
"""
np = _load_numpy()
data = np.fromstring(string, dtype=np.uint16)
data.resize((480, 640))
return dev, data, timestamp


def rgb_cb_np(dev, string, timestamp):
"""Converts the raw depth data into a numpy array for your function
Args:
dev: DevPtr object
string: A python string with the RGB data
timestamp: An int representing the time
Returns:
(dev, data, timestamp) where data is a 2D numpy array
"""
np = _load_numpy()
data = np.fromstring(string, dtype=np.uint8)
data.resize((480, 640, 3))
return dev, data, timestamp
16 changes: 16 additions & 0 deletions python/cython/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [Extension("freenect", ["freenect.pyx"],
extra_objects=["../../c/build/lib/libfreenect.a"],
libraries=['usb-1.0'],
extra_compile_args=['-fPIC', '-I', '../../c/include/',
'-I', '/usr/include/libusb-1.0/',
'-I', '/usr/local/include/libusb-1.0',
'-I', '/usr/local/include'])]
setup(
name = 'freenect',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
4 changes: 2 additions & 2 deletions python/demo_cv_depth_show.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python
from freenect import *
import freenect
import cv
import numpy as np

Expand All @@ -16,4 +16,4 @@ def display(dev, data, timestamp):
data.dtype.itemsize * data.shape[1])
cv.ShowImage('Depth', image)
cv.WaitKey(5)
runloop(depth=depth_cb_np_factory(display))
freenect.runloop(depth=lambda *x: display(*freenect.depth_cb_np(*x)))
4 changes: 2 additions & 2 deletions python/demo_cv_rgb_show.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python
from freenect import *
import freenect
import cv

cv.NamedWindow('RGB')
Expand All @@ -14,4 +14,4 @@ def display(dev, data, timestamp):
data.dtype.itemsize * 3 * data.shape[1])
cv.ShowImage('RGB', image)
cv.WaitKey(5)
runloop(rgb=rgb_cb_np_factory(display))
freenect.runloop(rgb=lambda *x: display(*freenect.rgb_cb_np(*x)))
4 changes: 2 additions & 2 deletions python/demo_mp_depth_show.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python
from freenect import *
import freenect
import matplotlib.pyplot as mp

mp.ion()
Expand All @@ -15,4 +15,4 @@ def display(dev, data, timestamp):
mp.draw()

if __name__ == '__main__':
runloop(depth=depth_cb_np_factory(display))
freenect.runloop(depth=lambda *x: display(*freenect.depth_cb_np(*x)))
4 changes: 2 additions & 2 deletions python/demo_mp_rgb_show.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
from freenect import *
import freenect
from demo_mp_depth_show import display
runloop(rgb=rgb_cb_np_factory(display))
freenect.runloop(rgb=lambda *x: display(*freenect.rgb_cb_np(*x)))
12 changes: 6 additions & 6 deletions python/demo_tilt.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python
from freenect import *
import freenect
import time
import threading
import random
Expand All @@ -16,14 +16,14 @@ def tilt_and_sense():
led = random.randint(0, 6)
tilt = random.randint(0, 30)
print('Led[%d] Tilt[%d]' % (led, tilt))
freenect_set_led(dev, led)
freenect_set_tilt_degs(dev, tilt)
print(raw_accel(dev))
print(mks_accel(dev))
freenect.set_led(dev, led)
freenect.set_tilt_degs(dev, tilt)
print(freenect.raw_accel(dev))
print(freenect.mks_accel(dev))
threading.Thread(target=tilt_and_sense).start()


def dev_getter(my_dev, *_):
global dev
dev = my_dev
runloop(depth=depth_cb_string_factory(dev_getter))
freenect.runloop(depth=lambda *x: dev_getter(*freenect.depth_cb_np(*x)))
Loading

0 comments on commit c8613d9

Please sign in to comment.