Skip to content

Commit 5c54a0b

Browse files
committed
feat: expose a function to apply depth registration - fixes #649
1 parent 837a8e9 commit 5c54a0b

File tree

7 files changed

+88
-62
lines changed

7 files changed

+88
-62
lines changed

CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ include (FindOS)
4646
include (SetupDirectories)
4747

4848
set (PROJECT_VER_MAJOR 0)
49-
set (PROJECT_VER_MINOR 6)
50-
set (PROJECT_VER_PATCH 3)
49+
set (PROJECT_VER_MINOR 7)
50+
set (PROJECT_VER_PATCH 0)
5151
set (PROJECT_VER
5252
"${PROJECT_VER_MAJOR}.${PROJECT_VER_MINOR}.${PROJECT_VER_PATCH}")
5353
set (PROJECT_APIVER
@@ -101,7 +101,7 @@ SET(DOC_OUTPUT_PATH ${CMAKE_BINARY_DIR}/doc)
101101
if (MSVC)
102102
set(C_FLAGS_WARNING "-W4")
103103
else ()
104-
set(C_FLAGS_WARNING "-Wall")
104+
set(C_FLAGS_WARNING "-Wall -Wno-unused-function")
105105
endif (MSVC)
106106

107107
set(C_CXX_FLAGS_DEFAULT "${C_FLAGS_WARNING} -O2")

examples/camtest.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,23 @@
2828
#include <stdio.h>
2929
#include <string.h>
3030
#include "libfreenect.h"
31+
#include "libfreenect_registration.h"
3132

3233
#ifndef SIGQUIT // win32 compat
3334
#define SIGQUIT SIGTERM
3435
#endif
3536

3637

38+
uint16_t mapped_depth[640 * 480];
39+
3740
void depth_cb(freenect_device* dev, void* data, uint32_t timestamp)
3841
{
3942
printf("Received depth frame at %d\n", timestamp);
43+
44+
int err = freenect_map_depth_to_video(dev, data, mapped_depth);
45+
if (err) {
46+
printf("Registration error %d\n", err);
47+
}
4048
}
4149

4250
void video_cb(freenect_device* dev, void* data, uint32_t timestamp)

fakenect/fakenect.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,18 +220,20 @@ int freenect_process_events(freenect_context *ctx)
220220
best as we can to match those from the original data and current run
221221
conditions (e.g., if it takes longer to run this code then we wait less).
222222
*/
223+
int err = 0;
224+
223225
if (!index_fp)
224226
open_index();
225227
char type;
226228
double record_cur_time;
227229
unsigned int timestamp, data_size;
228230
char *data = NULL;
229-
if (parse_line(&type, &record_cur_time, &timestamp, &data_size, &data)) {
230-
if (loop_playback) {
231+
err = parse_line(&type, &record_cur_time, &timestamp, &data_size, &data);
232+
if (err) {
233+
if (loop_playback) {
231234
close_index();
232235
return 0;
233-
} else
234-
return -1;
236+
} else return err;
235237
}
236238
// Sleep an amount that compensates for the original and current delays
237239
// playback_ is w.r.t. the current time
@@ -250,9 +252,9 @@ int freenect_process_events(freenect_context *ctx)
250252
case FREENECT_DEPTH_11BIT:
251253
memcpy(depth_buffer, cur_depth, mode.bytes);
252254
break;
253-
case FREENECT_DEPTH_REGISTERED:
254-
freenect_apply_registration(fake_dev, cur_depth, depth_buffer, true);
255-
break;
255+
case FREENECT_DEPTH_REGISTERED:
256+
err = freenect_apply_registration(&(fake_dev->registration), freenect_find_video_mode(mode.resolution, FREENECT_DEPTH_11BIT), cur_depth, depth_buffer);
257+
break;
256258
case FREENECT_DEPTH_MM:
257259
freenect_apply_depth_unpacked_to_mm(fake_dev, cur_depth, depth_buffer);
258260
break;
@@ -303,7 +305,7 @@ int freenect_process_events(freenect_context *ctx)
303305
}
304306
free(data);
305307
playback_prev_time = get_time();
306-
return 0;
308+
return err;
307309
}
308310

309311
int freenect_process_events_timeout(freenect_context *ctx, struct timeval *timeout)

include/libfreenect_registration.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,18 @@ FREENECTAPI void freenect_camera_to_world(freenect_device* dev,
125125
FREENECTAPI void freenect_map_rgb_to_depth( freenect_device* dev,
126126
uint16_t* depth_mm, uint8_t* rgb_raw, uint8_t* rgb_registered );
127127

128+
/**
129+
* Converts the depth_frame to output_mm and aligns it with the video frame.
130+
* This is similar to using the FREENECT_DEPTH_REGISTERED mode.
131+
*
132+
* @param dev freenect device
133+
* @param depth_frame depth frame buffer
134+
* @param output_mm output buffer which must have length at least width * height
135+
*
136+
* @return 0 on success
137+
*/
138+
FREENECTAPI int freenect_map_depth_to_video(freenect_device* dev, void* depth_frame, uint16_t* output_mm);
139+
128140
#ifdef __cplusplus
129141
}
130142
#endif

src/cameras.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ static void depth_process(freenect_device *dev, uint8_t *pkt, int len)
316316
convert_packed_to_16bit(dev->depth.raw_buf, (uint16_t*)dev->depth.proc_buf, 11, 640*480);
317317
break;
318318
case FREENECT_DEPTH_REGISTERED:
319-
freenect_apply_registration(dev, dev->depth.raw_buf, (uint16_t*)dev->depth.proc_buf, false);
319+
freenect_apply_registration(&(dev->registration), freenect_find_video_mode(dev->depth_resolution, FREENECT_DEPTH_11BIT_PACKED), dev->depth.raw_buf, (uint16_t*)dev->depth.proc_buf);
320320
break;
321321
case FREENECT_DEPTH_MM:
322322
freenect_apply_depth_to_mm(dev, dev->depth.raw_buf, (uint16_t*)dev->depth.proc_buf );

src/registration.c

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "libfreenect.h"
2828
#include "freenect_internal.h"
2929
#include "registration.h"
30+
#include "convert.h"
3031
#include <stdlib.h>
3132
#include <string.h>
3233
#include <stdio.h>
@@ -73,65 +74,56 @@ static void freenect_init_depth_to_rgb(int32_t* depth_to_rgb, freenect_zero_plan
7374
}
7475
}
7576

76-
// unrolled inner loop of the 11-bit unpacker
77-
static inline void unpack_8_pixels(uint8_t *raw, uint16_t *frame)
77+
// apply registration data to a single frame
78+
FN_INTERNAL int freenect_apply_registration(const freenect_registration* reg, const freenect_frame_mode input_mode, void* input, uint16_t* output_mm)
7879
{
79-
uint16_t baseMask = 0x7FF;
80-
81-
uint8_t r0 = *(raw+0);
82-
uint8_t r1 = *(raw+1);
83-
uint8_t r2 = *(raw+2);
84-
uint8_t r3 = *(raw+3);
85-
uint8_t r4 = *(raw+4);
86-
uint8_t r5 = *(raw+5);
87-
uint8_t r6 = *(raw+6);
88-
uint8_t r7 = *(raw+7);
89-
uint8_t r8 = *(raw+8);
90-
uint8_t r9 = *(raw+9);
91-
uint8_t r10 = *(raw+10);
92-
93-
frame[0] = (r0<<3) | (r1>>5);
94-
frame[1] = ((r1<<6) | (r2>>2) ) & baseMask;
95-
frame[2] = ((r2<<9) | (r3<<1) | (r4>>7) ) & baseMask;
96-
frame[3] = ((r4<<4) | (r5>>4) ) & baseMask;
97-
frame[4] = ((r5<<7) | (r6>>1) ) & baseMask;
98-
frame[5] = ((r6<<10) | (r7<<2) | (r8>>6) ) & baseMask;
99-
frame[6] = ((r8<<5) | (r9>>3) ) & baseMask;
100-
frame[7] = ((r9<<8) | (r10) ) & baseMask;
101-
}
80+
if (!reg || !input || !output_mm) return -1;
81+
if (!input_mode.is_valid) return -1;
82+
if (input_mode.resolution != FREENECT_RESOLUTION_MEDIUM) return -2;
83+
84+
if (input_mode.depth_format == FREENECT_DEPTH_REGISTERED) {
85+
memcpy(output_mm, input, input_mode.bytes);
86+
return 0;
87+
}
10288

103-
// apply registration data to a single packed frame
104-
FN_INTERNAL int freenect_apply_registration(freenect_device* dev, uint8_t* input, uint16_t* output_mm, bool unpacked)
105-
{
106-
freenect_registration* reg = &(dev->registration);
10789
// set output buffer to zero using pointer-sized memory access (~ 30-40% faster than memset)
10890
size_t i, *wipe = (size_t*)output_mm;
10991
for (i = 0; i < DEPTH_X_RES * DEPTH_Y_RES * sizeof(uint16_t) / sizeof(size_t); i++) wipe[i] = DEPTH_NO_MM_VALUE;
11092

111-
uint16_t unpack[8];
93+
uint16_t unpack[8] = { 0 };
11294

11395
uint32_t target_offset = DEPTH_Y_RES * reg->reg_pad_info.start_lines;
11496
uint32_t x,y,source_index = 8;
11597

11698
for (y = 0; y < DEPTH_Y_RES; y++) {
11799
for (x = 0; x < DEPTH_X_RES; x++) {
118100

119-
uint16_t metric_depth;
120-
121-
if (unpacked) {
122-
uint32_t buf_index = y * DEPTH_X_RES + x;
123-
metric_depth = reg->raw_to_mm_shift[((uint16_t *)input)[buf_index]];
124-
} else {
125-
// get 8 pixels from the packed frame
126-
if (source_index == 8) {
127-
unpack_8_pixels( input, unpack );
128-
source_index = 0;
129-
input += 11;
130-
}
131-
132-
// get the value at the current depth pixel, convert to millimeters
133-
metric_depth = reg->raw_to_mm_shift[ unpack[source_index++] ];
134-
}
101+
uint16_t metric_depth;
102+
103+
switch (input_mode.depth_format) {
104+
case FREENECT_DEPTH_MM:
105+
uint32_t mm_index = (y * input_mode.width) + x;
106+
metric_depth = ((uint16_t *)input)[mm_index];
107+
break;
108+
case FREENECT_DEPTH_11BIT: // as used by fakenect-record
109+
case FREENECT_DEPTH_10BIT: // todo: does this work?
110+
uint32_t buf_index = (y * input_mode.width) + x;
111+
metric_depth = reg->raw_to_mm_shift[((uint16_t *)input)[buf_index]];
112+
break;
113+
case FREENECT_DEPTH_11BIT_PACKED:
114+
case FREENECT_DEPTH_10BIT_PACKED:
115+
// get 8 pixels from the packed frame
116+
if (source_index == 8) {
117+
convert_packed_to_16bit(input, unpack, input_mode.data_bits_per_pixel, 8);
118+
source_index = 0;
119+
input += 11;
120+
}
121+
// get the value at the current depth pixel, convert to millimeters
122+
metric_depth = reg->raw_to_mm_shift[ unpack[source_index++] ];
123+
break;
124+
default:
125+
return -99;
126+
}
135127

136128
// so long as the current pixel has a depth value
137129
if (metric_depth == DEPTH_NO_MM_VALUE) continue;
@@ -175,17 +167,29 @@ FN_INTERNAL int freenect_apply_registration(freenect_device* dev, uint8_t* input
175167
return 0;
176168
}
177169

170+
FREENECTAPI int freenect_map_depth_to_video(freenect_device* dev, void* input, uint16_t* output_mm)
171+
{
172+
if (!dev || !input || !output_mm) return -1;
173+
174+
if (!dev->registration.registration_table) {
175+
freenect_init_registration(dev);
176+
}
177+
const freenect_registration* reg = &(dev->registration);
178+
const freenect_frame_mode depth_mode = freenect_get_current_depth_mode(dev);
179+
return freenect_apply_registration(reg, depth_mode, input, output_mm);
180+
}
181+
178182
// Same as freenect_apply_registration, but don't bother aligning to the RGB image
179183
FN_INTERNAL int freenect_apply_depth_to_mm(freenect_device* dev, uint8_t* input_packed, uint16_t* output_mm)
180184
{
181185
freenect_registration* reg = &(dev->registration);
182-
uint16_t unpack[8];
186+
uint16_t unpack[8] = { 0 };
183187
uint32_t x,y,source_index = 8;
184188
for (y = 0; y < DEPTH_Y_RES; y++) {
185189
for (x = 0; x < DEPTH_X_RES; x++) {
186190
// get 8 pixels from the packed frame
187191
if (source_index == 8) {
188-
unpack_8_pixels( input_packed, unpack );
192+
convert_packed_to_16bit(input_packed, output_mm, 11, 8);
189193
source_index = 0;
190194
input_packed += 11;
191195
}

src/registration.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626

2727
#pragma once
2828

29-
#include <stdbool.h>
29+
#include <stdint.h>
3030
#include "libfreenect.h"
3131

3232
// Internal function declarations relating to registration
3333
int freenect_init_registration(freenect_device* dev);
34-
int freenect_apply_registration(freenect_device* dev, uint8_t* input, uint16_t* output_mm, bool unpacked);
34+
int freenect_apply_registration(const freenect_registration* reg, const freenect_frame_mode depth_mode, void* depth_frame, uint16_t* output_mm);
3535
int freenect_apply_depth_to_mm(freenect_device* dev, uint8_t* input_packed, uint16_t* output_mm);
3636
int freenect_apply_depth_unpacked_to_mm(freenect_device* dev, uint16_t* input, uint16_t* output_mm);

0 commit comments

Comments
 (0)