Skip to content

Commit cbb5bfe

Browse files
committed
Merge pull request #395 from fran6co/rgb2depth
Add RGB -> depth mapping Reviewed-by: Benn Snyder <[email protected]>
2 parents 3c32fdb + 9069ddf commit cbb5bfe

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

include/libfreenect_registration.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ FREENECTAPI int freenect_destroy_registration(freenect_registration* reg);
120120
FREENECTAPI void freenect_camera_to_world(freenect_device* dev,
121121
int cx, int cy, int wz, double* wx, double* wy);
122122

123+
// helper function to map one FREENECT_VIDEO_RGB image to a FREENECT_DEPTH_MM
124+
// image (inverse mapping to FREENECT_DEPTH_REGISTERED, which is depth -> RGB)
125+
FREENECTAPI void freenect_map_rgb_to_depth( freenect_device* dev,
126+
uint16_t* depth_mm, uint8_t* rgb_raw, uint8_t* rgb_registered );
127+
123128
#ifdef __cplusplus
124129
}
125130
#endif

src/registration.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,73 @@ void freenect_camera_to_world(freenect_device* dev, int cx, int cy, int wz, doub
329329
*wy = (double)(cy - DEPTH_Y_RES/2) * factor;
330330
}
331331

332+
/// RGB -> depth mapping function (inverse of default FREENECT_DEPTH_REGISTERED mapping)
333+
void freenect_map_rgb_to_depth(freenect_device* dev, uint16_t* depth_mm, uint8_t* rgb_raw, uint8_t* rgb_registered)
334+
{
335+
uint32_t target_offset = dev->registration.reg_pad_info.start_lines * DEPTH_Y_RES;
336+
int x,y;
337+
int* map = (int*)malloc(DEPTH_Y_RES*DEPTH_X_RES* sizeof(int));
338+
unsigned short* zBuffer = (unsigned short*)malloc(DEPTH_Y_RES*DEPTH_X_RES* sizeof(unsigned short));
339+
memset(zBuffer, DEPTH_NO_MM_VALUE, DEPTH_X_RES*DEPTH_Y_RES * sizeof(unsigned short));
340+
341+
for (y = 0; y < DEPTH_Y_RES; y++) for (x = 0; x < DEPTH_X_RES; x++) {
342+
uint32_t index = y * DEPTH_X_RES + x;
343+
uint32_t cx,cy,cindex;
344+
345+
map[index] = -1;
346+
347+
int wz = depth_mm[index];
348+
349+
if (wz == DEPTH_NO_MM_VALUE) {
350+
continue;
351+
}
352+
353+
// coordinates in rgb image corresponding to x,y in depth image
354+
cx = (dev->registration.registration_table[index][0] + dev->registration.depth_to_rgb_shift[wz]) / REG_X_VAL_SCALE;
355+
cy = dev->registration.registration_table[index][1] - target_offset;
356+
357+
if (cx >= DEPTH_X_RES) continue;
358+
359+
cindex = cy*DEPTH_X_RES+cx;
360+
map[index] = cindex;
361+
362+
if (zBuffer[cindex] == DEPTH_NO_MM_VALUE || zBuffer[cindex] > wz) {
363+
zBuffer[cindex] = wz;
364+
}
365+
}
366+
367+
for (y = 0; y < DEPTH_Y_RES; y++) for (x = 0; x < DEPTH_X_RES; x++) {
368+
uint32_t index = y * DEPTH_X_RES + x;
369+
uint32_t cindex = map[index];
370+
371+
// pixels without depth data or out of bounds are black
372+
if (cindex == -1) {
373+
index *= 3;
374+
rgb_registered[index+0] = 0;
375+
rgb_registered[index+1] = 0;
376+
rgb_registered[index+2] = 0;
377+
378+
continue;
379+
}
380+
381+
unsigned short currentDepth = depth_mm[index];
382+
unsigned short minDepth = zBuffer[cindex];
383+
384+
// filters out pixels that are occluded
385+
if (currentDepth <= minDepth) {
386+
index *= 3;
387+
cindex *= 3;
388+
389+
rgb_registered[index+0] = rgb_raw[cindex+0];
390+
rgb_registered[index+1] = rgb_raw[cindex+1];
391+
rgb_registered[index+2] = rgb_raw[cindex+2];
392+
}
393+
}
394+
395+
free(zBuffer);
396+
free(map);
397+
}
398+
332399
/// Allocate and fill registration tables
333400
/// This function should be called every time a new video (not depth!) mode is
334401
/// activated.

0 commit comments

Comments
 (0)