Skip to content

Commit 5fff205

Browse files
author
Brandyn A. White
committed
Cleaned up demos as per this post
http://groups.google.com/group/openkinect/browse_thread/thread/c72b3ade917152de 1. Every demo that runs forever has a way to kill (which is printed when you start the program) 2. The normalization is now consistent (uses truncation which amiller and I believe is a nicer visualization than normalization) 3. Updated readme to include these changes 4. Added a new demo that sweeps through the depth image displaying slices of depth at a time 5. Added more visibility to the raw_tilt_state struct in freenect.pyx 6. Removed "../include/libfreenect.hpp" from src/CMake* as it doesn't exist there anymore Signed-off-by: Brandyn A. White <[email protected]>
1 parent b4a85f8 commit 5fff205

File tree

11 files changed

+159
-88
lines changed

11 files changed

+159
-88
lines changed

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ target_link_libraries (freenect ${LIBUSB_1_LIBRARIES})
3333
target_link_libraries (freenectstatic ${LIBUSB_1_LIBRARIES})
3434

3535
# Install the header file
36-
install (FILES "../include/libfreenect.h" "../include/libfreenect.hpp"
36+
install (FILES "../include/libfreenect.h"
3737
DESTINATION ${PROJECT_INCLUDE_INSTALL_DIR})
3838

3939
IF(UNIX AND NOT APPLE)

wrappers/python/README

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,25 @@ Install
1212
- Global Install: sudo python setup.py install
1313
- Local Directory Install: python setup.py build_ext --inplace
1414

15+
Why do the demos truncate the depth?
16+
The depth is 11 bits, if you want to display it as an 8 bit gray image you need to lose information somewhere. The truncation allows you to differentiate between local depth differences but doesn't give you the absolute depth due to ambiguities; however, normalization gives you the absolute depth differences between pixels but you will lose resolution due to the difference between high and low depths. We feel that this truncation produces the best results visually as a demo while being simple. See glview for an example of using colors to extend the range.
17+
18+
Do I need to call sync_stop when the program ends?
19+
No, it is not necessary.
20+
1521
Do you need to run everything with root?
1622
No. Use the udev drivers available in the project main directory.
1723

24+
Why does sync_multi call sync_stop after each kinect?
25+
The goal is to test multiple kinects, but some machines don't have the USB bandwidth for it. By default, this only lets one run at a time so that you can have many kinects on a hub or a slow laptop. You can comment out the line if your machine can handle it.
26+
1827
Differences From C Library
1928
Things that are intentially different to be more Pythonic
2029
- init/open_device: Different calling style (returns the new value as opposed to using a double pointer)
2130
- Names: Everything is in the freenect module. Since all freenect functions are of the form freenect_blah, we use freenect.blah to refer to them. This is also true for the synchronous calls.
2231

2332
Things not implemented (though could be added)
24-
- get/set user: Not implemented
25-
- Dev/Ctx/State: Opaque classes wrapping void *'s (you can't access struct elements)
33+
- Dev/Ctx: Opaque classes wrapping void *'s (you can't access struct elements)
2634
- Log functionality and callback
2735

2836
Additional Features

wrappers/python/demo_cv_async.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,39 @@
55

66
cv.NamedWindow('Depth')
77
cv.NamedWindow('RGB')
8+
keep_running = True
89

9-
die = False
1010

1111
def display_depth(dev, data, timestamp):
12-
data <<= (16-11) # 11 bits -> 16 bits
12+
global keep_running
13+
data = data.astype(np.uint8)
1314
image = cv.CreateImageHeader((data.shape[1], data.shape[0]),
14-
cv.IPL_DEPTH_16U,
15+
cv.IPL_DEPTH_8U,
1516
1)
1617
cv.SetData(image, data.tostring(),
1718
data.dtype.itemsize * data.shape[1])
1819
cv.ShowImage('Depth', image)
19-
global die
20-
if cv.WaitKey(5) == 27 : die = True
20+
if cv.WaitKey(10) == 27:
21+
keep_running = False
2122

22-
rgb = None
2323

2424
def display_rgb(dev, data, timestamp):
25-
global rgb
26-
if rgb is None :
27-
rgb = np.zeros(data.shape, np.uint8)
28-
rgb[:] = data[:, :, ::-1]
25+
global keep_running
2926
image = cv.CreateImageHeader((data.shape[1], data.shape[0]),
3027
cv.IPL_DEPTH_8U,
3128
3)
3229
# Note: We swap from RGB to BGR here
33-
cv.SetData(image, rgb,
30+
cv.SetData(image, data[:, :, ::-1].tostring(),
3431
data.dtype.itemsize * 3 * data.shape[1])
3532
cv.ShowImage('RGB', image)
36-
global die
37-
if cv.WaitKey(5) == 27 : die = True
33+
if cv.WaitKey(10) == 27:
34+
keep_running = False
3835

39-
def body(context, device) :
40-
if die : raise freenect.Kill
4136

37+
def body(*args):
38+
if not keep_running:
39+
raise freenect.Kill
40+
print('Press ESC in window to stop')
4241
freenect.runloop(depth=display_depth,
4342
video=display_rgb,
4443
body=body)
45-

wrappers/python/demo_cv_sync.py

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,11 @@
55

66
cv.NamedWindow('Depth')
77
cv.NamedWindow('Video')
8-
size = (640, 480)
9-
10-
# preallocate temporary images to avoid GC stalls and runtime memory allocs
11-
rgb=np.zeros((size[1],size[0],3),np.uint8)
12-
8+
print('Press ESC in window to stop')
139
while 1:
1410
depth, timestamp = freenect.sync_get_depth()
15-
bgr, timestamp = freenect.sync_get_video()
16-
17-
# maximize dynamic range of the given 11 bits into the used 16 bits
18-
depth<<=(16-11)
19-
# Reordering bgr as rgb
20-
# Using the slice directly doesn't work because the underlying buffer
21-
# is used and it does not change.
22-
rgb[:] = bgr[:,:,::-1]
23-
24-
cv.ShowImage('Depth', depth)
25-
cv.ShowImage('Video', rgb)
26-
if cv.WaitKey(10) == 27 : break
27-
28-
freenect.sync_stop()
29-
11+
rgb, timestamp = freenect.sync_get_video()
12+
cv.ShowImage('Depth', depth.astype(np.uint8))
13+
cv.ShowImage('Video', rgb[:, :, ::-1].astype(np.uint8))
14+
if cv.WaitKey(10) == 27:
15+
break

wrappers/python/demo_cv_sync_multi.py

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,21 @@
33
import cv
44
import numpy as np
55

6-
#cv.NamedWindow('Depth')
7-
#cv.NamedWindow('Video')
6+
cv.NamedWindow('Depth')
7+
cv.NamedWindow('Video')
88
ind = 0
9-
size = (640, 480)
10-
11-
# preallocate temporary images to avoid GC stalls and runtime memory allocs
12-
rgb=np.zeros((size[1],size[0],3),np.uint8)
13-
9+
print('Press ESC to stop')
1410
while 1:
1511
print(ind)
1612
try:
1713
depth, timestamp = freenect.sync_get_depth(ind)
18-
bgr, timestamp = freenect.sync_get_video(ind)
14+
rgb, timestamp = freenect.sync_get_video(ind)
1915
except TypeError:
2016
ind = 0
2117
continue
22-
# maximize dynamic range of the given 11 bits into the used 16 bits
23-
depth<<=(16-11)
24-
# Reordering bgr as rgb
25-
# Using the slice directly doesn't work because the underlying buffer
26-
# is used and it does not change.
27-
rgb[:] = bgr[:,:,::-1]
2818
ind += 1
29-
30-
cv.ShowImage('Depth %i'%ind, depth)
31-
cv.ShowImage('Video %i'%ind, rgb)
32-
if cv.WaitKey(10) == 27 : break
33-
34-
freenect.sync_stop()
35-
19+
cv.ShowImage('Depth', depth.astype(np.uint8))
20+
cv.ShowImage('Video', rgb[:, :, ::-1].astype(np.uint8))
21+
if cv.WaitKey(10) == 27:
22+
break
23+
freenect.sync_stop() # NOTE: May remove if you have good USB bandwidth
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env python
2+
"""Sweeps throught the depth image showing 100 range at a time"""
3+
import freenect
4+
import cv
5+
import numpy as np
6+
import time
7+
8+
cv.NamedWindow('Depth')
9+
10+
11+
def disp_thresh(lower, upper):
12+
depth, timestamp = freenect.sync_get_depth()
13+
depth = 255 * np.logical_and(depth > lower, depth < upper)
14+
cv.ShowImage('Depth', depth.astype(np.uint8))
15+
cv.WaitKey(10)
16+
lower = 0
17+
upper = 100
18+
max_upper = 2048
19+
while upper < max_upper:
20+
print('%d < depth < %d' % (lower, upper))
21+
disp_thresh(lower, upper)
22+
time.sleep(.1)
23+
lower += 20
24+
upper += 20

wrappers/python/demo_ipython.py

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
11
#!/usr/bin/env python
2-
from freenect import sync_get_depth, sync_get_video
3-
import cv
2+
import freenect
3+
import cv
44
import numpy as np
5-
5+
6+
67
def doloop():
78
global depth, rgb
89
while True:
910
# Get a fresh frame
10-
(depth,_), (rgb,_) = sync_get_depth(), sync_get_video()
11-
# Down sample 11 to 8 bits
12-
depth >>=(11-8)
11+
depth, _ = freenect.sync_get_depth()
12+
rgb, _ = freenect.sync_get_video()
1313
# Build a two panel color image
14-
d3 = np.dstack((depth,depth,depth)).astype(np.uint8)
15-
da = np.hstack((d3,rgb))
16-
14+
d3 = np.dstack((depth, depth, depth)).astype(np.uint8)
15+
da = np.hstack((d3, rgb))
1716
# Simple Downsample
18-
cv.ShowImage('both',np.array(da[::2,::2,::-1]))
19-
if cv.WaitKey(5) == 27 : break
20-
freenect.sync_stop()
21-
17+
cv.ShowImage('both', np.array(da[::2, ::2, ::-1]))
18+
if cv.WaitKey(10) == 27:
19+
break
20+
print('Press ESC in window to stop')
2221
doloop()
2322

2423
"""
2524
IPython usage:
2625
ipython
2726
[1]: run -i demo_freenect
2827
#<ctrl -c> (to interrupt the loop)
29-
[2]: %timeit -n100 sync_get_depth(), sync_get_rgb() # profile the kinect capture
30-
28+
[2]: %timeit -n100 sync_get_depth(), sync_get_rgb() # profile kinect capture
3129
"""
32-

wrappers/python/demo_mp_async.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
#!/usr/bin/env python
22
import freenect
33
import matplotlib.pyplot as mp
4+
import numpy as np
5+
import signal
46

57
mp.ion()
68
image_rgb = None
79
image_depth = None
10+
keep_running = True
811

912

1013
def display_depth(dev, data, timestamp):
1114
global image_depth
15+
data = data.astype(np.uint8)
16+
mp.gray()
1217
mp.figure(1)
1318
if image_depth:
1419
image_depth.set_data(data)
@@ -26,5 +31,17 @@ def display_rgb(dev, data, timestamp):
2631
image_rgb = mp.imshow(data, interpolation='nearest', animated=True)
2732
mp.draw()
2833

34+
35+
def body(*args):
36+
if not keep_running:
37+
raise freenect.Kill
38+
39+
40+
def handler(signum, frame):
41+
global keep_running
42+
keep_running = False
43+
print('Press Ctrl-C in terminal to stop')
44+
signal.signal(signal.SIGINT, handler)
2945
freenect.runloop(depth=display_depth,
30-
video=display_rgb)
46+
video=display_rgb,
47+
body=body)

wrappers/python/demo_mp_sync.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
11
#!/usr/bin/env python
22
import freenect
33
import matplotlib.pyplot as mp
4+
import numpy as np
5+
import signal
46

7+
keep_running = True
58
mp.ion()
69
mp.figure(1)
7-
image_depth = mp.imshow(freenect.sync_get_depth()[0], interpolation='nearest', animated=True)
10+
mp.gray()
11+
image_depth = mp.imshow(freenect.sync_get_depth()[0].astype(np.uint8),
12+
interpolation='nearest', animated=True)
813
mp.figure(2)
9-
image_rgb = mp.imshow(freenect.sync_get_video()[0], interpolation='nearest', animated=True)
14+
image_rgb = mp.imshow(freenect.sync_get_video()[0],
15+
interpolation='nearest', animated=True)
1016

11-
while 1:
17+
18+
def handler(signum, frame):
19+
"""Sets up the kill handler, catches SIGINT"""
20+
global keep_running
21+
keep_running = False
22+
print('Press Ctrl-C in terminal to stop')
23+
signal.signal(signal.SIGINT, handler)
24+
25+
while keep_running:
1226
mp.figure(1)
13-
image_depth.set_data(freenect.sync_get_depth()[0])
27+
image_depth.set_data(freenect.sync_get_depth()[0].astype(np.uint8))
1428
mp.figure(2)
1529
image_rgb.set_data(freenect.sync_get_video()[0])
1630
mp.draw()

wrappers/python/demo_tilt.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
#!/usr/bin/env python
22
import freenect
33
import time
4-
import threading
54
import random
6-
import time
5+
import signal
76

7+
keep_running = True
88
last_time = 0
99

1010

1111
def body(dev, ctx):
1212
global last_time
13+
if not keep_running:
14+
raise freenect.Kill
1315
if time.time() - last_time < 3:
1416
return
1517
last_time = time.time()
@@ -19,4 +21,11 @@ def body(dev, ctx):
1921
freenect.set_tilt_degs(dev, tilt)
2022
print('led[%d] tilt[%d] accel[%s]' % (led, tilt, freenect.get_accel(dev)))
2123

24+
25+
def handler(signum, frame):
26+
"""Sets up the kill handler, catches SIGINT"""
27+
global keep_running
28+
keep_running = False
29+
print('Press Ctrl-C in terminal to stop')
30+
signal.signal(signal.SIGINT, handler)
2231
freenect.runloop(body=body)

0 commit comments

Comments
 (0)