nl-knd_client 0.0.0.pre.usegit

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,212 @@
1
+ /*
2
+ * Non-inline definitions and functions for Kinect data pack/unpack code.
3
+ * (C)2011 Mike Bourgeous
4
+ */
5
+ #include <string.h>
6
+ #include <math.h>
7
+
8
+ #include <nlutils/nlutils.h>
9
+
10
+ #define UNPACK_INLINE
11
+ #include "unpack.h"
12
+
13
+ // TODO: Put ku_xworld, ku_yworld, lut into a library of addons, or submit as patches
14
+ // to libfreenect.
15
+
16
+ // Depth look-up table (translates depth sample into world-space millimeters).
17
+ int ku_depth_lut[2048];
18
+
19
+ // Converts x in pixels and z in world millimeters to x in world millimeters.
20
+ static int ku_xworld(int x, int zw)
21
+ {
22
+ // tan 28 ~= .53171 (1089 ~= .53171 * 2048)
23
+ // 0xcccd is the ~reciprocal of 10 (factor of W/2=320)
24
+ // Add 2**34 (0x400000000) for rounding before shift
25
+ // Shift right by 35:
26
+ // 11 bits for tangent (* 2048 above)
27
+ // 19 bits for reciprocal multiplication by 1/10 (factor of W/2=320)
28
+ // 5 bits for division by 32 (other factor of W/2=320)
29
+ //
30
+ // In total, with an overly generous maximum range of +/-16384mm (15
31
+ // bits), and an overhead of 35 bits due to arithmetic, 50 bits are
32
+ // needed for the calculation.
33
+ return (((int64_t)zw * (320 - x) * 1089 * 0xcccd) + 0x400000000) >> 35;
34
+ }
35
+
36
+ // Converts y in pixels and z in world millimeters to y in world millimeters.
37
+ static int ku_yworld(int y, int zw)
38
+ {
39
+ return ku_xworld(y + (640 - 480) / 2, zw);
40
+ }
41
+
42
+ // Initializes the depth look-up table.
43
+ // Copied from the knd daemon code, based on:
44
+ // http://groups.google.com/group/openkinect/browse_thread/thread/31351846fd33c78/e98a94ac605b9f21#e98a94ac605b9f21
45
+ void ku_init_lut()
46
+ {
47
+ int i;
48
+
49
+ for(i = 0; i < 2047; i++) {
50
+ ku_depth_lut[i] = (int)(0.1236f * tanf(i / 2842.5f + 1.1863f) * 1000.0f);
51
+ }
52
+ ku_depth_lut[2047] = 1048576;
53
+ }
54
+
55
+ // Finds the closest entry in the depth look-up table to the given world-space
56
+ // depth value in millimeters without going over. Uses a binary search.
57
+ int ku_reverse_lut(int zw)
58
+ {
59
+ int idx = PXZMAX / 2;
60
+ int off = PXZMAX / 4;
61
+
62
+ while(off > 0 && ku_depth_lut[idx] != zw) {
63
+ if(ku_depth_lut[idx] > zw) {
64
+ idx -= off;
65
+ } else if(ku_depth_lut[idx] < zw) {
66
+ idx += off;
67
+ }
68
+
69
+ off >>= 1;
70
+ }
71
+
72
+ // Binary search isn't perfect due to truncation, so find the optimum value
73
+ while(ku_depth_lut[idx] > zw && idx > 0) {
74
+ idx--;
75
+ }
76
+ while(ku_depth_lut[idx + 1] < zw && idx <= PXZMAX) {
77
+ idx++;
78
+ }
79
+
80
+ return idx;
81
+ }
82
+
83
+ // Plots a linear depth version of the given perspective image on the 8-bit
84
+ // output surface, which must be 640x480 bytes.
85
+ void plot_linear(const uint16_t *in, uint8_t *out)
86
+ {
87
+ int x, y, pix;
88
+
89
+ for(pix = 0, y = 0; y < 640; y++) {
90
+ for(x = 0; x < 480; x++, pix++) {
91
+ out[pix] = 255 - CLAMP(0, 255, ((int32_t)ku_depth_lut[(65535 - in[pix]) >> 5] - 400) * 255 / ZMAX);
92
+ }
93
+ }
94
+ }
95
+
96
+ // Turns overhead view coordinates into a pixel index.
97
+ #define OVPX(xw, zw) (((zw) * ZPIX / ZMAX) * XPIX + ((xw) * XPIX / XMAX + XPIX / 2))
98
+
99
+ // Plots an overhead view on the given raw linear 8-bit grayscale image
100
+ // surface, which must be XPIX bytes wide by ZPIX bytes tall.
101
+ void plot_overhead(const uint16_t *in, uint8_t *out)
102
+ {
103
+ int y, x, pix, val;
104
+ int xw, zw, opx;
105
+ int c;
106
+
107
+ memset(out, 0, XPIX * ZPIX);
108
+
109
+ // TODO: Draw borders
110
+
111
+ for(pix = 0, y = 0; y < 480; y++) {
112
+ for(x = 0; x < 640; x++, pix++) {
113
+ val = (65535 - in[pix]) >> 5;
114
+ zw = ku_depth_lut[val];
115
+ if(val >= 2047 || zw >= ZMAX) {
116
+ continue;
117
+ }
118
+ xw = ku_xworld(x, zw);
119
+
120
+ opx = OVPX(xw, zw);
121
+ if(opx < 0 || opx >= XPIX * ZPIX) {
122
+ continue;
123
+ }
124
+ c = out[opx];
125
+ c += 2;
126
+ if(c > 255) {
127
+ c = 255;
128
+ }
129
+ out[opx] = c;
130
+ }
131
+ }
132
+ }
133
+
134
+ // Turns side view coordinates into a pixel index.
135
+ #define SVPX(zw, yw) (((-yw) * YPIX / YMAX + YPIX / 2) * ZPIX + ((zw) * ZPIX / ZMAX))
136
+
137
+ // Plots a side view on the given raw linear 8-bit grayscale image surface,
138
+ // which must be ZPIX bytes wide by YPIX bytes tall.
139
+ void plot_side(const uint16_t *in, uint8_t *out)
140
+ {
141
+ int y, x, pix, val;
142
+ int yw, zw, opx;
143
+ int c;
144
+
145
+ memset(out, 0, ZPIX * YPIX);
146
+
147
+ // TODO: Draw borders
148
+ // TODO: Allow skipping for speed
149
+
150
+ for(pix = 0, y = 0; y < 480; y++) {
151
+ for(x = 0; x < 640; x++, pix++) {
152
+ val = (65535 - in[pix]) >> 5;
153
+ zw = ku_depth_lut[val];
154
+ if(val >= 2047 || zw >= ZMAX) {
155
+ continue;
156
+ }
157
+ yw = ku_yworld(y, zw);
158
+
159
+ opx = SVPX(zw, yw);
160
+ if(opx < 0 || opx >= ZPIX * YPIX) {
161
+ continue;
162
+ }
163
+ c = out[opx];
164
+ c += 2;
165
+ if(c > 255) {
166
+ c = 255;
167
+ }
168
+ out[opx] = c;
169
+ }
170
+ }
171
+ }
172
+
173
+ // Turns front view coordinates into a pixel index.
174
+ #define FVPX(xw, yw) (((-yw) * YPIX / YMAX + YPIX / 2) * XPIX + ((-xw) * XPIX / XMAX + XPIX / 2))
175
+
176
+ // Plots a front view on the given raw linear 8-bit grayscale image surface,
177
+ // which must be XPIX bytes wide by YPIX bytes tall.
178
+ void plot_front(const uint16_t *in, uint8_t *out)
179
+ {
180
+ int y, x, pix, val;
181
+ int xw, yw, zw, opx;
182
+ int c;
183
+
184
+ memset(out, 0, XPIX * YPIX);
185
+
186
+ // TODO: Draw borders
187
+ // TODO: Allow skipping for speed
188
+
189
+ for(pix = 0, y = 0; y < 480; y++) {
190
+ for(x = 0; x < 640; x++, pix++) {
191
+ val = (65535 - in[pix]) >> 5;
192
+ zw = ku_depth_lut[val];
193
+ if(val >= 2047 || zw >= ZMAX) {
194
+ continue;
195
+ }
196
+ xw = ku_xworld(x, zw);
197
+ yw = ku_yworld(y, zw);
198
+
199
+ opx = FVPX(xw, yw);
200
+ if(opx < 0 || opx >= XPIX * YPIX) {
201
+ continue;
202
+ }
203
+ c = out[opx];
204
+ c += 1 + (zw - 512) / 256; // TODO: Scale intensity by surface area
205
+ if(c > 255) {
206
+ c = 255;
207
+ }
208
+ out[opx] = c;
209
+ }
210
+ }
211
+ }
212
+
@@ -0,0 +1,108 @@
1
+ /*
2
+ * Definitions for Kinect data pack/unpack code.
3
+ * (C)2011 Mike Bourgeous
4
+ */
5
+ #ifndef UNPACK_H_
6
+ #define UNPACK_H_
7
+
8
+ #include <stdint.h>
9
+
10
+ #ifndef UNPACK_INLINE
11
+ #define UNPACK_INLINE inline
12
+ #endif /* UNPACK_INLINE */
13
+
14
+ // assuming xmax~=3.797 and ymax~=2.848 when z ~= 7
15
+ // calculated as x=5*tan(28)/tan(35) and y=x*3/4
16
+ #define XPIX 500
17
+ #define YPIX 500
18
+ #define ZPIX 500
19
+ #define XMAX 7594 // Actually 2*xmax
20
+ #define YMAX 5696 // Actually 2*ymax
21
+ #define ZMAX 7000
22
+ #define PXZMAX 1092
23
+
24
+
25
+ // Depth look-up table (translates depth sample into world-space millimeters).
26
+ extern int ku_depth_lut[2048];
27
+
28
+ // Unpacks and inverts 8 11-bit pixels (11 bytes) from in and stores them as
29
+ // MSB-aligned 16-bit values in out (16 bytes)
30
+ UNPACK_INLINE void unpack11_to_16(const uint8_t *in, uint16_t *out)
31
+ {
32
+ out[0] = 65535 - (((in[0] << 3) | (in[1] >> 5)) << 5);
33
+ out[1] = 65535 - ((((in[1] & 0x1f) << 6) | (in[2] >> 2)) << 5);
34
+ out[2] = 65535 - ((((in[2] & 0x03) << 9) | (in[3] << 1) | (in[4] >> 7)) << 5);
35
+ out[3] = 65535 - ((((in[4] & 0x7f) << 4) | (in[5] >> 4)) << 5);
36
+ out[4] = 65535 - ((((in[5] & 0x0f) << 7) | (in[6] >> 1)) << 5);
37
+ out[5] = 65535 - ((((in[6] & 0x01) << 10) | (in[7] << 2) | (in[8] >> 6)) << 5);
38
+ out[6] = 65535 - ((((in[8] & 0x3f) << 5) | (in[9] >> 3)) << 5);
39
+ out[7] = 65535 - ((((in[9] & 0x07) << 8) | in[10]) << 5);
40
+ }
41
+
42
+ // Packs 8 LSB-aligned 11-in-16-bit pixels (16 bytes) into 11 output bytes
43
+ UNPACK_INLINE void pack16_to_11(const uint16_t *in, uint8_t *out)
44
+ {
45
+ out[0] = in[0] >> 3;
46
+ out[1] = ((in[0] & 0x07) << 5) | (in[1] >> 6);
47
+ out[2] = ((in[1] & 0x3f) << 2) | (in[2] >> 9);
48
+ out[3] = (in[2] & 0x1fe) >> 1;
49
+ out[4] = ((in[2] & 0x01) << 7) | (in[3] >> 4);
50
+ out[5] = ((in[3] & 0x0f) << 4) | (in[4] >> 7);
51
+ out[6] = ((in[4] & 0x7f) << 1) | (in[5] >> 10);
52
+ out[7] = (in[5] & 0x3fc) >> 2;
53
+ out[8] = ((in[5] & 0x03) << 6) | (in[6] >> 5);
54
+ out[9] = ((in[6] & 0x1f) << 3) | (in[7] >> 8);
55
+ out[10] = in[7] & 0xff;
56
+ }
57
+
58
+ // Unpacks 8 11-bit pixels (11 bytes) into 8 output bytes
59
+ UNPACK_INLINE void unpack11_to_8(const uint8_t *in, uint8_t *out)
60
+ {
61
+ uint16_t buf16[8];
62
+ int i;
63
+
64
+ unpack11_to_16(in, buf16);
65
+ for(i = 0; i < 8; i++) {
66
+ out[i] = buf16[i] >> 3;
67
+ }
68
+ }
69
+
70
+ // Unpacks a single pixel into a right-aligned 16-bit value
71
+ UNPACK_INLINE int pxval_11(uint8_t *buf, int pixel)
72
+ {
73
+ uint32_t byteindex = (pixel * 11) >> 3;
74
+ uint32_t shiftbits = ((7 + pixel * 5) & 0x7) + 14;
75
+ uint32_t base;
76
+
77
+ buf = buf + byteindex;
78
+ base = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
79
+
80
+ return (base >> shiftbits) & 0x7ff;
81
+ }
82
+
83
+ // Initializes the depth look-up table.
84
+ // Copied from the knd daemon code, based on:
85
+ // http://groups.google.com/group/openkinect/browse_thread/thread/31351846fd33c78/e98a94ac605b9f21#e98a94ac605b9f21
86
+ void ku_init_lut();
87
+
88
+ // Finds the closest entry in the depth look-up table to the given world-space
89
+ // depth value in millimeters without going over. Uses a binary search.
90
+ int ku_reverse_lut(int zw);
91
+
92
+ // Plots a linear depth version of the given perspective image on the 8-bit
93
+ // output surface, which must be 640x480 bytes.
94
+ void plot_linear(const uint16_t *in, uint8_t *out);
95
+
96
+ // Plots an overhead view on the given raw linear 8-bit grayscale image
97
+ // surface, which must be XPIX bytes wide by ZPIX bytes tall.
98
+ void plot_overhead(const uint16_t *in, uint8_t *out);
99
+
100
+ // Plots a side view on the given raw linear 8-bit grayscale image surface,
101
+ // which must be ZPIX bytes wide by YPIX bytes tall.
102
+ void plot_side(const uint16_t *in, uint8_t *out);
103
+
104
+ // Plots a front view on the given raw linear 8-bit grayscale image surface,
105
+ // which must be XPIX bytes wide by YPIX bytes tall.
106
+ void plot_front(const uint16_t *in, uint8_t *out);
107
+
108
+ #endif /* UNPACK_H_ */
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Experimental Kinect depth image unpacking code.
3
+ * (C)2011 Mike Bourgeous
4
+ */
5
+ #include <stdio.h>
6
+ #include <stdint.h>
7
+
8
+ #include "unpack.h"
9
+
10
+ int main()
11
+ {
12
+ uint16_t in[640 * 480];
13
+ uint8_t out[XPIX * ZPIX];
14
+
15
+ if(fread(in, 2, 640 * 480, stdin) != 640 * 480) {
16
+ fprintf(stderr, "Must provide %d bytes of unpacked depth data to stdin.\n", 640 * 480 * 2);
17
+ }
18
+
19
+ ku_init_lut();
20
+ plot_overhead(in, out);
21
+
22
+ fwrite(out, 1, XPIX * ZPIX, stdout);
23
+
24
+ return 0;
25
+ }
26
+
@@ -0,0 +1,42 @@
1
+ /*
2
+ * Code to render a basic grid for the overhead view, for later manipulation.
3
+ * The final grid will be created from this program's output using the GIMP.
4
+ * (C)2012 Mike Bourgeous
5
+ */
6
+ #include <stdio.h>
7
+ #include <stdint.h>
8
+ #include <string.h>
9
+
10
+ #include "unpack.h"
11
+
12
+ void draw_grid(uint8_t *grid, uint8_t color, int spacing)
13
+ {
14
+ int x, z;
15
+
16
+ // Loop through x in world space, z in pixels
17
+ for(x = 0; x < XMAX / 2; x += spacing) {
18
+ for(z = 0; z < ZPIX; z++) {
19
+ grid[x * XPIX / XMAX + XPIX / 2 + z * XPIX] = color;
20
+ grid[XPIX / 2 - (x * XPIX / XMAX) + z * XPIX] = color;
21
+ }
22
+ }
23
+
24
+ // Loop through z in world space, x in pixels
25
+ for(z = 0; z < ZMAX; z += spacing) {
26
+ for(x = 0; x < XPIX; x++) {
27
+ grid[x + z * ZPIX / ZMAX * XPIX] = color;
28
+ }
29
+ }
30
+ }
31
+
32
+ int main()
33
+ {
34
+ uint8_t out[XPIX * ZPIX];
35
+
36
+ memset(out, 0, sizeof(out));
37
+ draw_grid(out, 128, 500);
38
+ draw_grid(out, 255, 1000);
39
+ fwrite(out, 1, sizeof(out), stdout);
40
+
41
+ return 0;
42
+ }
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Experimental Kinect depth image unpacking code.
3
+ * (C)2011 Mike Bourgeous
4
+ */
5
+ #include <stdio.h>
6
+ #include <stdint.h>
7
+
8
+ #include "unpack.h"
9
+
10
+ int main()
11
+ {
12
+ uint16_t in[640 * 480];
13
+ uint8_t out[ZPIX * YPIX];
14
+
15
+ if(fread(in, 2, 640 * 480, stdin) != 640 * 480) {
16
+ fprintf(stderr, "Must provide %d bytes of unpacked depth data to stdin.\n", 640 * 480 * 2);
17
+ }
18
+
19
+ ku_init_lut();
20
+ plot_side(in, out);
21
+
22
+ fwrite(out, 1, sizeof(out), stdout);
23
+
24
+ return 0;
25
+ }
26
+
@@ -0,0 +1,42 @@
1
+ /*
2
+ * Code to render a basic grid for the side view, for later manipulation.
3
+ * The final grid will be created from this program's output using the GIMP.
4
+ * (C)2012 Mike Bourgeous
5
+ */
6
+ #include <stdio.h>
7
+ #include <stdint.h>
8
+ #include <string.h>
9
+
10
+ #include "unpack.h"
11
+
12
+ void draw_grid(uint8_t *grid, uint8_t color, int spacing)
13
+ {
14
+ int y, z;
15
+
16
+ // Loop through y in world space, z in piyels
17
+ for(y = 0; y < YMAX / 2; y += spacing) {
18
+ for(z = 0; z < ZPIX; z++) {
19
+ grid[y * YPIX / YMAX * ZPIX + YPIX / 2 * ZPIX + z] = color;
20
+ grid[YPIX / 2 * ZPIX - (y * YPIX / YMAX * ZPIX) + z] = color;
21
+ }
22
+ }
23
+
24
+ // Loop through z in world space, y in piyels
25
+ for(z = 0; z < ZMAX; z += spacing) {
26
+ for(y = 0; y < YPIX; y++) {
27
+ grid[y * ZPIX + z * ZPIX / ZMAX] = color;
28
+ }
29
+ }
30
+ }
31
+
32
+ int main()
33
+ {
34
+ uint8_t out[YPIX * ZPIX];
35
+
36
+ memset(out, 0, sizeof(out));
37
+ draw_grid(out, 128, 500);
38
+ draw_grid(out, 255, 1000);
39
+ fwrite(out, 1, sizeof(out), stdout);
40
+
41
+ return 0;
42
+ }