diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt old mode 100755 new mode 100644 index 13c98fc4..7a4d18ad --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -20,6 +20,7 @@ endif() add_executable(glview glview.c) add_executable(regview regview.c) add_executable(hiview hiview.c) +add_executable(kinect_register kinect_register.c) if(BUILD_AUDIO) add_executable(wavrecord wavrecord.c) add_executable(micview micview.c) @@ -40,6 +41,7 @@ if(APPLE) target_link_libraries(glview freenect) target_link_libraries(regview freenect) target_link_libraries(hiview freenect) + target_link_libraries(kinect_register freenect) if (BUILD_AUDIO) target_link_libraries(wavrecord freenect) target_link_libraries(micview freenect) @@ -56,11 +58,12 @@ else() find_package(OpenGL REQUIRED) find_package(GLUT REQUIRED) - include_directories(${OPENGL_INCLUDE_DIRS} ${GLUT_INCLUDE_DIRS} ${USB_INCLUDE_DIRS}) + include_directories(${OPENGL_INCLUDE_DIRS} ${GLUT_INCLUDE_DIR} ${USB_INCLUDE_DIRS}) target_link_libraries(glview freenect ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MATH_LIB}) target_link_libraries(regview freenect ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MATH_LIB}) target_link_libraries(hiview freenect ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MATH_LIB}) + target_link_libraries(kinect_register freenect ${CMAKE_THREAD_LIBS_INIT}) if (BUILD_AUDIO) target_link_libraries(wavrecord freenect ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MATH_LIB}) target_link_libraries(micview freenect ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MATH_LIB}) @@ -74,7 +77,7 @@ else() endif() -install (TARGETS glview regview hiview +install (TARGETS glview regview hiview kinect_register DESTINATION bin) if (BUILD_C_SYNC) diff --git a/examples/kinect_register.c b/examples/kinect_register.c new file mode 100644 index 00000000..93ec8c1b --- /dev/null +++ b/examples/kinect_register.c @@ -0,0 +1,473 @@ +/* + * This file is part of the OpenKinect Project. http://www.openkinect.org + * + * Copyright (c) 2010 individual OpenKinect contributors. See the CONTRIB file + * for details. + * + * This code is licensed to you under the terms of the Apache License, version + * 2.0, or, at your option, the terms of the GNU General Public License, + * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses, + * or the following URLs: + * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.gnu.org/licenses/gpl-2.0.txt + * + * If you redistribute this file in source form, modified or unmodified, you + * may: + * 1) Leave this header intact and distribute it under the same terms, + * accompanying it with the APACHE20 and GPL20 files, or + * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or + * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file + * In all cases you must keep the copyright notice intact and include a copy + * of the CONTRIB file. + * + * Binary distributions must follow the binary distribution requirements of + * either License. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define DEPTH_MAX_METRIC_VALUE 10000 +#define DEPTH_MAX_RAW_VALUE 2048 +#define DEPTH_NO_MM_VALUE 0 + +#define DEPTH_X_RES 640 +#define DEPTH_Y_RES 480 + +#define REG_X_VAL_SCALE 256 // "fixed-point" precision for double -> int32_t conversion + + +void dump_registration(char* regfile) { + printf("Dumping Kinect registration to %s\n", regfile); + + freenect_context *f_ctx; + if (freenect_init(&f_ctx, NULL) < 0) { + printf("freenect_init() failed\n"); + exit(0); + } + + freenect_set_log_level(f_ctx, FREENECT_LOG_DEBUG); + freenect_select_subdevices(f_ctx, + (freenect_device_flags)(FREENECT_DEVICE_MOTOR | FREENECT_DEVICE_CAMERA)); + + freenect_device *f_dev; + int user_device_number = 0; + if (freenect_open_device(f_ctx, &f_dev, user_device_number) < 0) { + printf("Could not open device\n"); + exit(0); + } + + freenect_registration dev; + dev = freenect_copy_registration( f_dev ); + + FILE* fp = fopen(regfile, "w"); + if (!fp) { + printf("Error: Cannot open file '%s'\n", regfile); + exit(1); + } + + // from freenect_copy_registration in registration.c + /* + dev.reg_info = dev->registration.reg_info; + dev.reg_pad_info = dev->registration.reg_pad_info; + dev.zero_plane_info = dev->registration.zero_plane_info; + dev.const_shift = dev->registration.const_shift; + dev.raw_to_mm_shift = (uint16_t*)malloc( sizeof(uint16_t) * DEPTH_MAX_RAW_VALUE ); + dev.depth_to_rgb_shift = (int32_t*)malloc( sizeof( int32_t) * DEPTH_MAX_METRIC_VALUE ); + dev.registration_table = (int32_t (*)[2])malloc( sizeof( int32_t) * DEPTH_X_RES * DEPTH_Y_RES * 2 ); + */ + + /* Should be ~2.4 MB + printf( "\n\n%d\n\n", sizeof(dev)+ + sizeof(uint16_t)*DEPTH_MAX_RAW_VALUE + + sizeof(int32_t)*DEPTH_MAX_METRIC_VALUE + + sizeof(int32_t)*DEPTH_X_RES*DEPTH_Y_RES*2 ); + */ + + // write out first four fields + fwrite( &dev.reg_info, sizeof(dev.reg_info), 1, fp ); + fwrite( &dev.reg_pad_info, sizeof(dev.reg_pad_info), 1, fp); + fwrite( &dev.zero_plane_info, sizeof(dev.zero_plane_info), 1, fp); + fwrite( &dev.const_shift, sizeof(dev.const_shift), 1, fp); + + //printf( "\n\n%d\n\n", sizeof(uint16_t)*DEPTH_MAX_RAW_VALUE ); // 4096 + fwrite( (&dev)->raw_to_mm_shift, sizeof(uint16_t), DEPTH_MAX_RAW_VALUE, fp ); + + //printf( "\n\n%d\n\n", sizeof(int32_t)*DEPTH_MAX_METRIC_VALUE ); // 4000 + fwrite( (&dev)->depth_to_rgb_shift, sizeof(int32_t), DEPTH_MAX_METRIC_VALUE, fp ); + + //printf( "\n\n%d\n\n", sizeof(int32_t)*DEPTH_X_RES*DEPTH_Y_RES*2 ); // 2457600 + fwrite( (&dev)->registration_table, sizeof(int32_t), DEPTH_X_RES*DEPTH_Y_RES*2, fp ); + + fclose(fp); +} + + +freenect_registration load_registration(char* regfile) +{ + + FILE *fp = NULL; + /* load the regdump file */ + fp = fopen(regfile, "r"); + if (!fp) { + perror(regfile); + exit(1); + } + + freenect_registration reg; + // allocate memory and set up pointers + // (from freenect_copy_registration in registration.c) + reg.raw_to_mm_shift = (uint16_t*)malloc( sizeof(uint16_t) * DEPTH_MAX_RAW_VALUE ); + reg.depth_to_rgb_shift = (int32_t*)malloc( sizeof( int32_t) * DEPTH_MAX_METRIC_VALUE ); + reg.registration_table = (int32_t (*)[2])malloc( sizeof( int32_t) * DEPTH_X_RES * DEPTH_Y_RES * 2 ); + // load (inverse of kinect_regdump) + fread( ®.reg_info, sizeof(reg.reg_info), 1, fp ); + fread( ®.reg_pad_info, sizeof(reg.reg_pad_info), 1, fp); + fread( ®.zero_plane_info, sizeof(reg.zero_plane_info), 1, fp); + fread( ®.const_shift, sizeof(reg.const_shift), 1, fp); + fread( reg.raw_to_mm_shift, sizeof(uint16_t), DEPTH_MAX_RAW_VALUE, fp ); + fread( reg.depth_to_rgb_shift, sizeof(int32_t), DEPTH_MAX_METRIC_VALUE, fp ); + fread( reg.registration_table, sizeof(int32_t), DEPTH_X_RES*DEPTH_Y_RES*2, fp ); + fclose(fp); + + return reg; +} + + +void load_PGM(char *PGMfile, uint16_t* data) +{ + FILE *fp = NULL; + fp = fopen(PGMfile, "r"); + if (!fp) { + perror(PGMfile); + exit(1); + } + while (getc(fp) != '\n'); // skip header line + fread(data, sizeof(uint16_t), DEPTH_X_RES*DEPTH_Y_RES, fp); + fclose(fp); +} + +void load_PPM(char *PPMfile, uint8_t* data) +{ + // written like this: + //fprintf(fp, "P6 %d %d 255\n", FREENECT_FRAME_W, FREENECT_FRAME_H); + //fwrite(data, data_size, 1, fp); + FILE *fp = NULL; + fp = fopen(PPMfile, "r"); + if (!fp) { + perror(PPMfile); + exit(1); + } + while (getc(fp) != '\n'); // skip P6 header + fread(data, sizeof(uint8_t), DEPTH_X_RES*DEPTH_Y_RES*3, fp); +} + +void write_PPM(char *PPMfile, uint8_t* data) +{ + char *PPMfile_out = (char *)malloc(strlen(PPMfile) + 4); // ".reg" + sprintf(PPMfile_out, "%s", PPMfile); + sprintf(PPMfile_out+strlen(PPMfile)-4, "%s", ".reg"); + sprintf(PPMfile_out+strlen(PPMfile), "%s", ".ppm"); + + FILE *fp = NULL; + fp = fopen(PPMfile_out, "w"); + if (!fp) { + perror(PPMfile_out); + exit(1); + } + + fprintf(fp, "P6 %d %d 255\n", DEPTH_X_RES, DEPTH_Y_RES); + fwrite(data, DEPTH_X_RES*DEPTH_Y_RES*3, 1, fp); + fclose(fp); +} + +void write_PGM(char *PGMfile, uint16_t* data, char *type) +{ + // make filename .dist.pgm + char *PGMfile_out = (char *)malloc(strlen(PGMfile) + 2); // '.x' + sprintf(PGMfile_out, "%s", PGMfile); + sprintf(PGMfile_out+strlen(PGMfile)-3, "%s", type); + sprintf(PGMfile_out+strlen(PGMfile)-2, "%s", ".pgm"); + + FILE *fp = NULL; + fp = fopen(PGMfile_out, "w"); + if (!fp) { + perror(PGMfile_out); + exit(1); + } + + fprintf(fp, "P5 %d %d 65535\n", DEPTH_X_RES, DEPTH_Y_RES ); + fwrite(data, sizeof(uint16_t), DEPTH_X_RES*DEPTH_Y_RES, fp); + fclose(fp); +} + + +void write_xyz_bin(char *infile, double* x, double* y, uint16_t* z) +{ + FILE* fp; + // make filename .x + char *file_out = (char *)malloc(strlen(infile) + 10); + sprintf(file_out, "%s", infile); + + // X + sprintf(file_out+strlen(infile)-3, "%s", "x"); + fp = NULL; + fp = fopen(file_out, "w"); + if (!fp) { + perror(file_out); + exit(1); + } + fwrite(x, sizeof(double), DEPTH_X_RES*DEPTH_Y_RES, fp); + fclose(fp); + + // Y + sprintf(file_out+strlen(infile)-3, "%s", "y"); + fp = NULL; + fp = fopen(file_out, "w"); + if (!fp) { + perror(file_out); + exit(1); + } + fwrite(y, sizeof(double), DEPTH_X_RES*DEPTH_Y_RES, fp); + fclose(fp); + + // Z + sprintf(file_out+strlen(infile)-3, "%s", "z"); + fp = NULL; + fp = fopen(file_out, "w"); + if (!fp) { + perror(file_out); + exit(1); + } + fwrite(z, sizeof(uint16_t), DEPTH_X_RES*DEPTH_Y_RES, fp); + fclose(fp); +} + + +void write_PLY(char *outfile, double* x, double* y, uint16_t* z, uint8_t* rgb) +{ + FILE *fp; + int i; + fp = fopen(outfile, "w"); + if (!fp) { + perror(outfile); + exit(1); + } + + int nel=0; + for (i=0; i<(DEPTH_X_RES*DEPTH_Y_RES); i++) { + if (x[i] == 0 && y[i] == 0) + continue; + if (z[i] == 0) + continue; + nel++; + } + + fprintf(fp, "ply\n"); + fprintf(fp, "format ascii 1.0\n"); + fprintf(fp, "comment Generated by kinect_register program\n"); + fprintf(fp, "comment Author: Ken Mankoff\n"); + fprintf(fp, "comment Citation: http://dx.doi.org/10.1002/esp.3332\n"); + fprintf(fp, "element vertex %d\n", nel); + fprintf(fp, "property float x\n"); + fprintf(fp, "property float y\n"); + fprintf(fp, "property float z\n"); + if (rgb != 0) { + fprintf(fp, "property float r\n"); + fprintf(fp, "property float g\n"); + fprintf(fp, "property float b\n"); + } + //fprintf(fp, "property list uchar int vertex_index\n"); + fprintf(fp, "end_header\n"); + + for (i=0; i<(DEPTH_X_RES*DEPTH_Y_RES); i++) { + + if (x[i] == 0 && y[i] == 0) + continue; + + if (z[i] == 0) + continue; + + fprintf(fp, "%d %d %d", (int16_t)x[i], (int16_t)y[i], z[i]); + if (rgb != 0) { + int ii = i*3; + fprintf( fp, " %d %d %d", + (uint8_t)rgb[ii], + (uint8_t)rgb[ii+1], + (uint8_t)rgb[ii+2]); + } + fprintf(fp, "\n"); + nel++; + } + fclose(fp); + +} + +// RGB -> depth mapping function (inverse of default FREENECT_DEPTH_REGISTERED mapping) +// From Florian +void freenect_map_rgb_to_depth(freenect_registration* reg, uint16_t* depth_mm, uint8_t* rgb_raw, uint8_t* rgb_registered) +{ + uint32_t target_offset = reg->reg_pad_info.start_lines * DEPTH_Y_RES; + int x,y; + + for (y = 0; y < DEPTH_Y_RES; y++) for (x = 0; x < DEPTH_X_RES; x++) { + + uint32_t index = y * DEPTH_X_RES + x; + uint32_t cx,cy,cindex; + + int wz = depth_mm[index]; + //if (wz == 0) continue; + + // coordinates in rgb image corresponding to x,y + cx = (reg->registration_table[index][0] + reg->depth_to_rgb_shift[wz]) / REG_X_VAL_SCALE; + cy = reg->registration_table[index][1]; + + if (cx >= DEPTH_X_RES) continue; + + cindex = (cy * DEPTH_X_RES + cx - target_offset) * 3; + index = index*3; + + rgb_registered[index+0] = rgb_raw[cindex+0]; + rgb_registered[index+1] = rgb_raw[cindex+1]; + rgb_registered[index+2] = rgb_raw[cindex+2]; + } +} + +void apply_registration(char* regfile, char* PGMfile, char* PPMfile) +{ + int i, j; + int x, y; + + freenect_registration reg; + reg = load_registration(regfile); + + uint16_t data[DEPTH_X_RES*DEPTH_Y_RES]; + load_PGM(PGMfile, data); + + uint8_t data_ppm[DEPTH_X_RES*DEPTH_Y_RES*3]; + uint8_t data_ppm_reg[DEPTH_X_RES*DEPTH_Y_RES*3]; + if (PPMfile != NULL) { + load_PPM(PPMfile, data_ppm); + // write_PPM(PPMfile, data_ppm); + } + + // freenect_apply_depth_to_mm from registration.c + // This converts the raw data to depth data, but does not mess with + // pixel alignment. + uint16_t wz[DEPTH_X_RES*DEPTH_Y_RES]; + double wx[DEPTH_X_RES*DEPTH_Y_RES], wy[DEPTH_X_RES*DEPTH_Y_RES]; + for (y = 0; y < DEPTH_Y_RES; y++) { + for (x = 0; x < DEPTH_X_RES; x++) { + // get the value at the current depth pixel, convert to millimeters + uint16_t metric_depth = (®)->raw_to_mm_shift[ data[y*DEPTH_X_RES+x] ]; + wz[y * DEPTH_X_RES + x] = metric_depth < DEPTH_MAX_METRIC_VALUE ? metric_depth : DEPTH_MAX_METRIC_VALUE; + } + } + // write_PGM( PGMfile, wz, "d" ); + + if (PPMfile != 0) { + freenect_map_rgb_to_depth(®, wz, data_ppm, data_ppm_reg); + write_PPM(PPMfile, data_ppm_reg); + } + + // see freenect_camera_to_world() in registration.c + double ref_pix_size = reg.zero_plane_info.reference_pixel_size; + double ref_distance = reg.zero_plane_info.reference_distance; + double factor; + uint32_t idx = 0; + for (j=0; j | -a []\n" + " -h: Display this help message\n" + " -s: Save the registration parameters from a connected Kinect to \n" + " -a: Apply the registration parameters from to (from 'record')\n" + " Optionally align a PPM file with the PGM file\n" + "\n" + "Data Formats (units: mm):\n" + " file.x: 640x480 double of x values\n" + " file.y: 640x480 double of y values\n" + " file.z: 640x480 integer of z values\n" + " file.ply: ASCII PLY file of x y z r g b. RGB only if PPM argument provided\n" + " file.reg.ppm: PPM shifted so pixels align with file.{x,y,z} data\n" + "\n" + ); + exit(0); +} + +int main(int argc, char **argv) +{ + int c=1; + char *regfile=0, *PGMfile=0, *PPMfile=0; + if (argc == 1) + usage(); + + while (c < argc) { + if (strcmp(argv[c],"-h")==0) + usage(); + else if (strcmp(argv[c],"-s")==0) { + if (argc <= (c+1)) + usage(); + regfile = argv[c+1]; + } + else if (strcmp(argv[c],"-a")==0) { + if (argc <= (c+2)) + usage(); + regfile = argv[c+1]; + PGMfile = argv[c+2]; + if (argc == (c+4)) { + PPMfile = argv[c+3]; + //printf("Will register color too...\n"); + } + } + c++; + } + + if (regfile != 0 && PGMfile == 0) + dump_registration(regfile); + else + apply_registration(regfile, PGMfile, PPMfile); + + return 0; +} diff --git a/examples/wavrecord.c b/examples/wavrecord.c index c7abc697..655b39ef 100644 --- a/examples/wavrecord.c +++ b/examples/wavrecord.c @@ -93,6 +93,7 @@ int main(int argc, char** argv) { } capture state; + state.samples = 0; state.logfiles[0] = fopen("channel1.wav", "wb"); state.logfiles[1] = fopen("channel2.wav", "wb"); state.logfiles[2] = fopen("channel3.wav", "wb"); diff --git a/src/loader.c b/src/loader.c index f5bf0585..0451b1fb 100644 --- a/src/loader.c +++ b/src/loader.c @@ -193,11 +193,37 @@ FN_INTERNAL int upload_firmware(fnusb_dev* dev) { return -errno; } // Now we have an open firmware file handle. - uint32_t addr = 0x00080000; - int read; + firmware_header fwheader; + int read = 0; + read = fread(&fwheader, 1, sizeof(firmware_header), fw); + if (read != sizeof(firmware_header)) { + FN_ERROR("upload_firmware: firmware image too small, has no header?\n"); + fclose(fw); + return -errno; + } + // The file is serialized as little endian. + fwheader.magic = fn_le32(fwheader.magic); + fwheader.ver_major = fn_le16(fwheader.ver_major); + fwheader.ver_minor = fn_le16(fwheader.ver_minor); + fwheader.ver_release = fn_le16(fwheader.ver_release); + fwheader.ver_patch = fn_le16(fwheader.ver_patch); + fwheader.base_addr = fn_le32(fwheader.base_addr); + fwheader.size = fn_le32(fwheader.size); + fwheader.entry_addr = fn_le32(fwheader.entry_addr); + FN_INFO("Found firmware image:\n"); + FN_INFO("\tmagic %08X\n", fwheader.magic); + FN_INFO("\tversion %02d.%02d.%02d.%02d\n", fwheader.ver_major, fwheader.ver_minor, fwheader.ver_release, fwheader.ver_patch); + FN_INFO("\tbase address 0x%08x\n", fwheader.base_addr); + FN_INFO("\tsize 0x%08x\n", fwheader.size); + FN_INFO("\tentry point 0x%08x\n", fwheader.entry_addr); + + rewind(fw); + uint32_t addr = fwheader.base_addr; unsigned char page[0x4000]; + int total_bytes_sent = 0; do { - read = fread(page, 1, 0x4000, fw); + size_t block_size = (0x4000 > fwheader.size - total_bytes_sent) ? fwheader.size - total_bytes_sent : 0x4000; + read = fread(page, 1, block_size, fw); if(read <= 0) { break; } @@ -224,6 +250,7 @@ FN_INTERNAL int upload_firmware(fnusb_dev* dev) { return -1; } bytes_sent += to_send; + total_bytes_sent += to_send; } res = get_reply(dev); addr += (uint32_t)read; @@ -231,11 +258,15 @@ FN_INTERNAL int upload_firmware(fnusb_dev* dev) { } while (read > 0); fclose(fw); fw = NULL; + if (total_bytes_sent != fwheader.size) { + FN_ERROR("upload_firmware: firmware image declared %d bytes, but file only contained %d bytes\n", fwheader.size, total_bytes_sent); + return -1; + } bootcmd.tag = fn_le32(dev->parent->audio_tag); bootcmd.bytes = fn_le32(0); bootcmd.cmd = fn_le32(0x04); - bootcmd.addr = fn_le32(0x00080030); + bootcmd.addr = fn_le32(fwheader.entry_addr); dump_bl_cmd(ctx, bootcmd); res = fnusb_bulk(dev, 1, (unsigned char*)&bootcmd, sizeof(bootcmd), &transferred); if(res != 0 || transferred != sizeof(bootcmd)) { diff --git a/src/loader.h b/src/loader.h index 82782205..dcec08aa 100644 --- a/src/loader.h +++ b/src/loader.h @@ -39,6 +39,17 @@ typedef struct { uint32_t unk; } bootloader_command; +typedef struct { + uint32_t magic; // Magic bytes. 2BL uses 0xF00BACCA, audios uses 0xCA77F00D + uint16_t ver_minor; // The version string has four parts, each a 16-bit little-endian int. + uint16_t ver_major; // Yes, minor comes before major. + uint16_t ver_release; // + uint16_t ver_patch; // + uint32_t base_addr; // Base address of firmware image. 2BL starts at 0x10000, audios starts at 0x80000. + uint32_t size; // Size of firmware image, in bytes + uint32_t entry_addr; // Code entry point (absolute address) +} firmware_header; + typedef struct { uint32_t magic; uint32_t tag; diff --git a/wrappers/python/freenect.pyx b/wrappers/python/freenect.pyx index c76ba301..162561f5 100644 --- a/wrappers/python/freenect.pyx +++ b/wrappers/python/freenect.pyx @@ -49,6 +49,8 @@ cdef extern from "libfreenect.h": FREENECT_DEPTH_10BIT FREENECT_DEPTH_11BIT_PACKED FREENECT_DEPTH_10BIT_PACKED + FREENECT_DEPTH_REGISTERED + FREENECT_DEPTH_MM ctypedef enum freenect_led_options: FREENECT_LED_OFF "LED_OFF" @@ -148,6 +150,8 @@ DEPTH_11BIT = FREENECT_DEPTH_11BIT DEPTH_10BIT = FREENECT_DEPTH_10BIT DEPTH_11BIT_PACKED = FREENECT_DEPTH_11BIT_PACKED DEPTH_10BIT_PACKED = FREENECT_DEPTH_10BIT_PACKED +DEPTH_REGISTERED = FREENECT_DEPTH_REGISTERED +DEPTH_MM = FREENECT_DEPTH_MM LED_OFF = FREENECT_LED_OFF LED_GREEN = FREENECT_LED_GREEN LED_RED = FREENECT_LED_RED @@ -476,7 +480,7 @@ def sync_get_depth(index=0, format=DEPTH_11BIT): if out: error_open_device() return - if format == DEPTH_11BIT: + if format in [DEPTH_11BIT, DEPTH_10BIT, DEPTH_MM, DEPTH_REGISTERED]: dims[0], dims[1] = 480, 640 return PyArray_SimpleNewFromData(2, dims, npc.NPY_UINT16, data), timestamp else: