Guía de Desarrollo Orbbec Femto Bolt: Configuración Completa del SDK y Tutorial de Programación

Última actualización: marzo de 2026

Comenzar con el Orbbec Femto Bolt es sencillo. Esta guía de desarrollo integral cubre la configuración del SDK, tutoriales de programación y ejemplos prácticos de código para ayudarte a construir aplicaciones potentes de visión 3D.

Guía de Desarrollo del Orbbec Femto Bolt: Configuración Completa del SDK y Tutorial de Programación

¿Qué es el Orbbec Femto Bolt?

El Orbbec Femto Bolt es una cámara de profundidad de alto rendimiento basada en la tecnología de Tiempo de Vuelo (ToF), desarrollada en colaboración entre Orbbec y Microsoft, basada en la probada tecnología de profundidad Azure Kinect. Este dispositivo compacto pero potente ofrece imágenes RGB 4K junto con capacidades precisas de sensado de profundidad, lo que lo convierte en una opción ideal para desarrolladores que trabajan en aplicaciones de IA, robótica, realidad aumentada y visión por computadora. Lo que distingue al Femto Bolt es su compatibilidad API con el SDK Microsoft Azure Kinect a través del Orbbec SDK K4A Wrapper, permitiendo a los desarrolladores aprovechar bases de código existentes de Azure Kinect con modificaciones mínimas. La cámara soporta dos modos de profundidad: Campo de Visión Amplio (WFOV) de 120 grados para escaneo de áreas grandes y Campo de Visión Estrecho (NFOV) de 75 grados para mediciones precisas, manteniendo una precisión de profundidad menor a 11mm más 0.1% de la distancia medida. Ya sea que estés construyendo robots autónomos, desarrollando sistemas de captura de video volumétrico o creando experiencias inmersivas de AR, el Femto Bolt ofrece las capacidades del sensor y la flexibilidad del software necesarias para hacer realidad tu visión.

Comprendiendo la Arquitectura Técnica del Femto Bolt

Tecnología de Sensado de Profundidad por Tiempo de Vuelo

El Femto Bolt emplea tecnología avanzada de Tiempo de Vuelo (ToF) que opera a una longitud de onda de 850nm, un espectro cuidadosamente elegido que equilibra los requisitos de seguridad ocular con una sensibilidad óptima del sensor. A diferencia de los sistemas tradicionales de visión estereoscópica que dependen de la coincidencia de características entre dos cámaras, las cámaras ToF miden la profundidad directamente calculando el tiempo que tarda la luz infrarroja modulada en viajar desde el sensor hasta los objetos en la escena y reflejarse de vuelta. Este enfoque de iluminación activa ofrece varias ventajas significativas: precisión constante en la profundidad independientemente de la textura de la escena, procesamiento más rápido ya que no se requiere extracción de características, y rendimiento fiable en superficies planas o sin textura que desafían a los algoritmos de coincidencia estereoscópica.

El sensor ToF de 1 megapíxel de la cámara captura datos de profundidad en todo el campo de visión simultáneamente, permitiendo el mapeo de profundidad en tiempo real a hasta 30 cuadros por segundo dependiendo del modo seleccionado. La longitud de onda infrarroja de 850 nm es particularmente adecuada para aplicaciones en interiores porque es invisible para los humanos mientras se refleja fuertemente en la mayoría de los materiales comunes. El rango dinámico del sensor le permite manejar condiciones de luz variables dentro de su entorno operativo, aunque se debe evitar la luz solar directa ya que puede saturar los elementos del detector y degradar la precisión de la medición.

Operación de modo dual de profundidad

La versatilidad del Femto Bolt proviene de su soporte para dos modos distintos de operación de profundidad, cada uno optimizado para diferentes escenarios de aplicación. El modo WFOV (Campo de Visión Amplio) captura datos de profundidad a una resolución de 1024x1024 píxeles en un campo de visión horizontal y vertical de 120 grados, haciéndolo perfecto para mapeo ambiental, navegación robótica en espacios congestionados y proyectos de escaneo de áreas grandes. Este modo opera a 15 cuadros por segundo y puede detectar objetos hasta a 5.46 metros de distancia, proporcionando una cobertura completa de grandes entornos con mínimas reposiciones de la cámara.

El modo NFOV (Campo de Visión Estrecho) sacrifica amplitud por precisión, operando a una resolución de 640x576 con un campo de visión horizontal de 75 grados y vertical de 65 grados, mientras duplica la tasa de cuadros a 30 FPS. Este modo es ideal para aplicaciones que requieren mediciones detalladas: inspección de control de calidad, tareas de reconocimiento de objetos, escaneo biométrico y manipulación precisa en robótica. La mayor tasa de cuadros también beneficia escenas dinámicas donde la cámara o los objetos están en movimiento, reduciendo el desenfoque por movimiento en los datos de profundidad y asegurando un seguimiento más preciso.

Sistema integrado de cámara RGB 4K

Más allá de sus capacidades de detección de profundidad, el Femto Bolt incorpora una cámara RGB 4K de alta resolución capaz de capturar imágenes a color con hasta 3840x2160 píxeles. Esta cámara cuenta con un campo de visión horizontal de 80 grados y vertical de 51 grados, proporcionando una cobertura ligeramente más estrecha que el modo WFOV del sensor de profundidad, pero ofreciendo un detalle significativamente mayor para análisis visual. La cámara soporta imágenes de Alto Rango Dinámico (HDR), lo que le permite manejar condiciones de iluminación desafiantes donde coexisten áreas brillantes y oscuras en la misma escena.

Quizás lo más importante es que la cámara RGB realiza un registro sincronizado por hardware con los datos de profundidad, asegurando que cada píxel en la imagen a color tenga un valor de profundidad correspondiente. Esta integración estrecha elimina la necesidad de procesamiento de alineación por software y garantiza que la información de color y profundidad permanezca perfectamente sincronizada incluso durante movimientos rápidos de la cámara o en escenas dinámicas. Los sistemas automáticos de exposición y balance de blancos trabajan continuamente para mantener una calidad óptima de imagen en condiciones de iluminación variables, aunque también hay controles manuales disponibles para aplicaciones que requieren precisión en el color.

Integración de la Unidad de Medición Inercial

La Unidad de Medición Inercial (IMU) integrada de 6 ejes combina un acelerómetro de 3 ejes con un giroscopio de 3 ejes, proporcionando capacidades esenciales de detección de movimiento que mejoran muchas aplicaciones de cámaras de profundidad. En contextos robóticos, los datos del IMU pueden fusionarse con algoritmos de odometría visual para mejorar la precisión de localización y mantener la continuidad del seguimiento durante breves oclusiones de la cámara. Para aplicaciones de realidad aumentada, el IMU ayuda a rastrear la orientación y el movimiento del dispositivo, contribuyendo a un registro estable de superposiciones en la vista del usuario.

Los datos del IMU fluyen a aproximadamente 1.6 kHz, proporcionando actualizaciones de movimiento de alta frecuencia que complementan los cuadros de profundidad y color de 15-30 FPS. Las marcas de tiempo del IMU están sincronizadas con los cuadros de la cámara, permitiendo una fusión precisa de datos en sus aplicaciones. Esta combinación de detección visual de profundidad con mediciones inerciales crea una base robusta para SLAM (Localización y Mapeo Simultáneos), reconocimiento de gestos, detección de vibraciones y cualquier aplicación que requiera conciencia tanto del entorno visual como del movimiento del dispositivo.

Configuración de su entorno de desarrollo

Configuración del entorno de desarrollo en Windows

Desarrollar aplicaciones para el Femto Bolt en Windows requiere configurar Visual Studio 2019 o posterior con herramientas de desarrollo en C++, junto con el Orbbec SDK K4A Wrapper que proporciona compatibilidad API con aplicaciones Azure Kinect. Comience instalando Visual Studio con la carga de trabajo "Desarrollo de escritorio con C++", asegurándose de incluir los componentes del SDK de Windows 10. Luego, descargue la última versión del Orbbec SDK K4A Wrapper desde el repositorio oficial de GitHub, seleccionando los binarios precompilados para Windows para evitar tiempo de compilación.

Antes de usar la cámara, debe ejecutar el script de registro de metadatos UVC que permite la comunicación adecuada entre Windows y la cámara de profundidad conectada por USB. Abra PowerShell como Administrador y navegue al directorio de scripts dentro del SDK, luego ejecute el comando de instalación:

cd src/orbbec/OrbbecSDK/misc/scripts
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
.\obsensor_metadata_win10.ps1 -op install_all

Este script registra las capacidades de metadatos USB Video Class de la cámara con Windows, permitiendo el acceso a la marca de tiempo y otros metadatos esenciales para el correcto funcionamiento de la cámara de profundidad. Sin este paso, puede que encuentre problemas donde el dispositivo es reconocido pero los cuadros de profundidad no están disponibles o las marcas de tiempo son incorrectas.

Configuración del Entorno de Desarrollo en Linux

El desarrollo en Linux requiere instalar numerosas dependencias de compilación antes de compilar o usar el SDK. El siguiente comando instala todos los paquetes requeridos en distribuciones basadas en Ubuntu:

sudo apt update
sudo apt install -y \
    pkg-config \
    ninja-build \
    doxygen \
    clang \
    gcc-multilib \
    g++-multilib \
    python3 \
    nasm \
    libgl1-mesa-dev \
    libsoundio-dev \
    libvulkan-dev \
    libx11-dev \
    libxcursor-dev \
    libxinerama-dev \
    libxrandr-dev \
    libusb-1.0-0-dev \
    libssl-dev \
    libudev-dev \
    mesa-common-dev \
    uuid-dev

Después de instalar las dependencias, debe configurar las reglas de udev para permitir el acceso a la cámara sin ser root. El SDK incluye un script de instalación que crea los permisos necesarios para el dispositivo:

cd src/orbbec/OrbbecSDK/misc/scripts
sudo chmod +x ./install_udev_rules.sh
sudo ./install_udev_rules.sh

Esta configuración de udev asegura que cualquier usuario en el grupo video pueda acceder al Femto Bolt sin requerir privilegios de root. Después de agregarse al grupo video con sudo usermod -a -G video $USER y cerrando sesión y volviendo a iniciarla, podrá acceder a la cámara como un usuario normal.

Para compilar el SDK desde el código fuente, clone el repositorio y sus submódulos, luego configure y compile:

git clone https://github.com/orbbec/OrbbecSDK-K4A-Wrapper.git
cd OrbbecSDK-K4A-Wrapper
git submodule update --init --recursive
mkdir build \&\& cd build
cmake .. -G Ninja
ninja
sudo ninja install

Configuración de la Plataforma Embebida NVIDIA Jetson

El Femto Bolt es totalmente compatible con las plataformas NVIDIA Jetson, incluyendo AGX Orin, Orin NX, Orin Nano, AGX Xavier y Xavier NX, permitiendo aplicaciones de IA en el borde que requieren procesamiento local sin conectividad a la nube. Comience flasheando su dispositivo Jetson con el último SDK JetPack de NVIDIA, asegurándose de seleccionar la versión JetPack adecuada para su hardware.

El procedimiento de instalación en Linux descrito arriba se aplica a dispositivos Jetson que ejecutan distribuciones L4T (Linux para Tegra) basadas en Ubuntu. El sistema de compilación CMake detecta automáticamente la arquitectura ARM64 y compila los binarios apropiados. Para un rendimiento óptimo, asegúrese de que su Jetson esté funcionando en modo de máximo rendimiento:

sudo nvpmodel -m 0
sudo jetson_clocks

Estos comandos habilitan todos los núcleos de la CPU a la máxima frecuencia y configuran la GPU para un rendimiento sostenido. Al integrarse con aplicaciones CUDA, recuerde que la GPU del Jetson puede usarse para procesamiento acelerado de profundidad, generación de nubes de puntos y tareas de inferencia de IA.

Análisis Profundo del Kit de Desarrollo de Software

Comprendiendo la Arquitectura del Wrapper K4A

El SDK Orbbec K4A Wrapper representa una solución elegante para desarrolladores que desean aprovechar los ecosistemas existentes de Azure Kinect mientras se benefician del hardware rentable de Orbbec. Este wrapper traduce cada llamada en la API del Azure Kinect Sensor SDK a funciones correspondientes del SDK de Orbbec internamente, creando una capa de compatibilidad sin fisuras que normalmente no requiere cambios en el código más allá de la sustitución del archivo de la biblioteca. El wrapper está construido sobre Azure Kinect Sensor SDK v1.4.1, asegurando estabilidad de la API y soporte completo de funciones.

Cuando su aplicación llama a funciones como k4a_device_open() o k4a_device_start_cameras(), el wrapper intercepta estas llamadas y las dirige a la implementación correspondiente del SDK de Orbbec. Esta traducción ocurre de forma transparente, permitiendo que las bases de código existentes de Azure Kinect funcionen en hardware Femto Bolt con mínima fricción. El wrapper soporta tanto la rama principal (v1) como la rama v2-main (v2) del SDK de Orbbec, dándole flexibilidad para elegir implementaciones estables o de vanguardia.

El soporte del dispositivo varía según la versión del firmware, y el SDK impone requisitos mínimos para garantizar un funcionamiento adecuado. El Femto Bolt requiere una versión mínima de firmware 1.1.2, siendo la versión 1.1.2 la recomendada para una compatibilidad óptima. Puede verificar la versión del firmware de su dispositivo usando las funciones de enumeración de dispositivos del SDK o las utilidades de visor incluidas.

Compatibilidad y diferencias de la API

Aunque el K4A Wrapper ofrece una amplia compatibilidad con la API, los desarrolladores deben estar al tanto de varias diferencias con respecto al SDK nativo de Azure Kinect. La más notable es el tipo de campo del desplazamiento de la marca de tiempo de grabación: el SDK de Orbbec usa uint64_t start_timestamp_offset_usec mientras Azure Kinect usa uint32_t start_timestamp_offset_usec. Las aplicaciones que usan explícitamente este campo requerirán reemplazo del archivo de encabezado o compilación condicional.

Varias interfaces de Azure Kinect no están implementadas en el K4A Wrapper, aunque rara vez se necesitan en la mayoría de las aplicaciones:

  • Funciones personalizadas de asignación de memoria (k4a_set_allocator())
  • Funciones de lectura y ajuste de temperatura
  • Controles manuales de exposición, balance de blancos y velocidad ISO a nivel de imagen
  • Detección del estado del conector del cable de sincronización

Para la gran mayoría de las aplicaciones de cámaras de profundidad, estas funciones no implementadas no afectarán la funcionalidad. Sin embargo, si está migrando código especializado de Azure Kinect que depende de estas características, necesitará implementar enfoques alternativos o aceptar una funcionalidad reducida.

Desarrollo en Python con pyk4a

Los desarrolladores de Python pueden aprovechar el Femto Bolt a través de la biblioteca pyk4a, que proporciona una interfaz Pythonica para la API compatible con Azure Kinect subyacente. Instale el paquete usando pip:

pip install pyk4a

La biblioteca pyk4a simplifica la inicialización de la cámara y la captura de fotogramas en llamadas a métodos intuitivas. Aquí hay un ejemplo básico que captura fotogramas sincronizados de profundidad y color:

from pyk4a import PyK4A, Config, ColorResolution, DepthMode

# Configurar ajustes de la cámara
config = Config(
    color_resolution=ColorResolution.RES_720P,
    depth_mode=DepthMode.NFOV_UNBINNED,
    camera_fps=30,
    synchronized_images_only=True
)

# Inicializar y arrancar la cámara
k4a = PyK4A(config=config)
k4a.start()

try:
    # Capturar 100 cuadros
    for frame_count in range(100):
        capture = k4a.get_capture()

        # Acceder a la imagen de profundidad como array numpy
        depth = capture.depth
        print(f"Cuadro de profundidad {frame_count}: {depth.shape}")

        # Acceder a la imagen de color
        color = capture.color
        print(f"Cuadro de color {frame_count}: {color.shape}")

        # Acceder a la imagen IR si está disponible
        if capture.ir is not None:
            print(f"Cuadro IR: {capture.ir.shape}")

finally:
    k4a.stop()

La biblioteca pyk4a devuelve imágenes de profundidad y color como arrays numpy, facilitando la integración con OpenCV, pipelines de procesamiento basados en NumPy y frameworks de aprendizaje automático. La biblioteca también soporta configuración de sincronización de hardware para configuraciones multi-cámara y proporciona acceso conveniente a datos IMU.

Wrappers Alternativos para Python

Más allá de pyk4a, los desarrolladores Python tienen opciones adicionales para acceder a los datos de Femto Bolt. El oficial azure-kinect-python El paquete proporciona enlaces directos al SDK de Azure Kinect, ofreciendo paridad de funciones con la API de C++ para aplicaciones que requieren control completo:

pip install azure-kinect-python

Este paquete sigue la estructura de la API de C++ más de cerca que pyk4a, lo que puede ser preferible para desarrolladores que migran desde C++ o que requieren características específicas del SDK no expuestas a través de la interfaz de conveniencia de pyk4a.

Para visualización y procesamiento 3D, Open3D ofrece herramientas potentes que se integran bien con datos de cámaras de profundidad:

pip install open3d

Open3D puede procesar imágenes de profundidad del Femto Bolt y convertirlas automáticamente en nubes de puntos coloreadas, realizar registro entre múltiples capturas de profundidad y ofrecer utilidades de visualización interactivas. Las estructuras de datos de la biblioteca están optimizadas para la manipulación eficiente de millones de puntos, lo que la hace adecuada para aplicaciones de reconstrucción y mapeo 3D.

Conceptos Básicos de Programación y Ejemplos

Inicialización y Configuración del Dispositivo

La base de cualquier aplicación Femto Bolt es la correcta inicialización del dispositivo y configuración de la cámara. El SDK utiliza una estructura de configuración que controla todos los parámetros de la cámara antes de iniciar la tubería de captura. Entender cada opción de configuración te permite optimizar la cámara para los requisitos específicos de tu aplicación.

La estructura de configuración incluye ajustes para la resolución de color, modo de profundidad, cuadros por segundo, captura de imagen sincronizada, retardo de profundidad, retardo de color, modo de sincronización por cable y compensación de retardo subordinado. Aquí se explica cómo configurar la cámara para una aplicación típica:

#include <k4a/k4a.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    // Obtener el número de dispositivos conectados
    uint32_t device_count = k4a_device_get_installed_count();
    if (device_count == 0) {
        printf("¡No se encontraron dispositivos Azure Kinect!\n");
        return 1;
    }

    // Abrir el dispositivo predeterminado
    k4a_device_t device = NULL;
    if (k4a_device_open(K4A_DEVICE_DEFAULT, &device) != K4A_RESULT_SUCCEEDED) {
        printf("Error al abrir el dispositivo\n");
        return 1;
    }

    // Configurar parámetros de la cámara
    k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;

    // Habilitar cámara de profundidad
    config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED;
    config.camera_fps = K4A_FRAMES_PER_SECOND_30;

    // Habilitar cámara de color con resolución 720p
    config.color_resolution = K4A_COLOR_RESOLUTION_720P;
    config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32;

    // Habilitar captura sincronizada
    config.synchronized_images_only = true;

    // Establecer retraso de profundidad a color para alineación
    config.depth_delay_off_color_usec = 0;

    // Configurar sincronización por cable (modo independiente)
    config.wired_sync_mode = K4A_WIRED_SYNC_MODE_STANDALONE;

    // Iniciar las cámaras
    if (k4a_device_start_cameras(device, &config) != K4A_RESULT_SUCCEEDED) {
        printf("Error al iniciar las cámaras\n");
        k4a_device_close(device);
        return 1;
    }

    printf("Cámara iniciada con éxito\n");
    printf("Modo de profundidad: %d\n", config.depth_mode);
    printf("Resolución de color: %d\n", config.color_resolution);
    printf("Frecuencia de cuadros: %d FPS\n", config.camera_fps);

    // ... aquí iría el código de captura de cuadros ...

    // Limpieza
    k4a_device_stop_cameras(device);
    k4a_device_close(device);

    return 0;
}

El K4A_DEVICE_CONFIG_INIT_DISABLE_ALL La macro inicializa la estructura de configuración con todas las cámaras deshabilitadas, permitiéndote habilitar selectivamente solo lo que tu aplicación necesita. Este enfoque explícito previene que valores predeterminados inesperados afecten el comportamiento de tu aplicación.

Captura y procesamiento de cuadros

Capturar cuadros del Femto Bolt implica solicitar capturas del dispositivo y extraer los tipos de imagen deseados. El SDK usa un enfoque basado en espera donde tu aplicación se bloquea hasta que un cuadro completo está disponible, asegurando la entrega sincronizada de datos. Aquí hay un ejemplo completo que muestra el manejo adecuado de cuadros:

#include <k4a/k4a.h>
#include <stdio.h>
#include <stdlib.h>

void process_depth_image(k4a_image_t depth_image) {
    if (depth_image == NULL) {
        return;
    }

    // Obtener propiedades de la imagen
    int width = k4a_image_get_width_pixels(depth_image);
    int height = k4a_image_get_height_pixels(depth_image);
    int stride = k4a_image_get_stride_bytes(depth_image);
    uint8_t* buffer = k4a_image_get_buffer(depth_image);

    // Obtener la marca de tiempo
    uint64_t timestamp = k4a_image_get_timestamp_usec(depth_image);
    printf("Cuadro de profundidad a %llu us: %dx%d (stride=%d)\n", 
           (unsigned long long)timestamp, width, height, stride);

    // Acceder a valores de profundidad sin procesar (enteros sin signo de 16 bits)
    uint16_t* depth_data = (uint16_t*)buffer;

    // Ejemplo: Encontrar el valor mínimo de profundidad en el cuadro
    uint16_t min_depth = UINT16_MAX;
    for (int i = 0; i < width * height; i++) {
        uint16_t depth_value = depth_data[i];
        if (depth_value != 0 && depth_value < min_depth) {
            min_depth = depth_value;
        }
    }

    // Convertir a milímetros (la profundidad está en mm)
    printf("Profundidad mínima en el cuadro: %.2f metros\n", min_depth / 1000.0f);
}

void process_color_image(k4a_image_t color_image) {
    if (color_image == NULL) {
        return;
    }

    int width = k4a_image_get_width_pixels(color_image);
    int height = k4a_image_get_height_pixels(color_image);
    int stride = k4a_image_get_stride_bytes(color_image);
    k4a_image_format_t format = k4a_image_get_format(color_image);

    printf("Cuadro de color: %dx%d (formato=%d, stride=%d)\n", 
           width, height, format, stride);
}

int main() {
    k4a_device_t device = NULL;
    k4a_device_open(K4A_DEVICE_DEFAULT, &device);

    k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
    config.depth_mode = K4A_DEPTH_MODE_WFOV_UNBINNED;
    config.color_resolution = K4A_COLOR_RESOLUTION_1080P;
    config.camera_fps = K4A_FRAMES_PER_SECOND_15;
    config.synchronized_images_only = true;

    k4a_device_start_cameras(device, &config);

    // Capturar 100 cuadros
    for (int frame_index = 0; frame_index < 100; frame_index++) {
        // Esperar una captura (tiempo de espera de 1000ms)
        k4a_capture_t capture = NULL;
        k4a_wait_result_t result = k4a_device_get_capture(device, &capture, 1000);

        if (result == K4A_WAIT_RESULT_SUCCEEDED) {
            // Extraer y procesar imagen de profundidad
            k4a_image_t depth_image = k4a_capture_get_depth_image(capture);
            process_depth_image(depth_image);
            if (depth_image != NULL) {
                k4a_image_release(depth_image);
            }

            // Extraer y procesar imagen de color
            k4a_image_t color_image = k4a_capture_get_color_image(capture);
            process_color_image(color_image);
            if (color_image != NULL) {
                k4a_image_release(color_image);
            }

            // Liberar la captura cuando se termine
            k4a_capture_release(capture);
        }
        else if (result == K4A_WAIT_RESULT_TIMEOUT) {
            printf("Tiempo de espera agotado para la captura\n");
        }
        else {
            printf("Error al obtener la captura\n");
            break;
        }
    }

    k4a_device_stop_cameras(device);
    k4a_device_close(device);

    return 0;
}

El objeto de captura contiene referencias a todas las imágenes sincronizadas (profundidad, color, IR y versiones transformadas opcionalmente). Siempre libera las capturas e imágenes cuando termines para evitar fugas de memoria. El SDK gestiona los buffers internos y los reutiliza entre cuadros para mayor eficiencia.

Generación de Nube de Puntos

Una de las capacidades más potentes del Femto Bolt es generar nubes de puntos 3D transformando datos de profundidad en coordenadas espaciales. El SDK incluye funciones integradas para esta transformación que manejan automáticamente la calibración intrínseca de la cámara:

#include <k4a/k4a.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Estructura para contener un punto 3D
typedef struct {
    float x, y, z;
    uint8_t r, g, b;
} PointXYZRGB;

void generate_point_cloud(k4a_image_t depth_image, 
                         k4a_image_t color_image,
                         PointXYZRGB** points_out,
                         int* point_count_out) {
    // Obtener propiedades de la imagen de profundidad
    int depth_width = k4a_image_get_width_pixels(depth_image);
    int depth_height = k4a_image_get_height_pixels(depth_image);
    uint8_t* depth_buffer = k4a_image_get_buffer(depth_image);

    // Obtener propiedades de la imagen de color
    int color_width = 0, color_height = 0;
    uint8_t* color_buffer = NULL;
    if (color_image != NULL) {
        color_width = k4a_image_get_width_pixels(color_image);
        color_height = k4a_image_get_height_pixels(color_image);
        color_buffer = k4a_image_get_buffer(color_image);
    }

    // Obtener calibración para la transformación
    k4a_calibration_t calibration;
    // (Asumir que la calibración del dispositivo ya está obtenida)

    // Crear manejador de transformación
    k4a_transformation_t transformation = k4a_transformation_create(&calibration);

    // Crear imagen de profundidad transformada (alineada al color)
    k4a_image_t transformed_depth = NULL;
    k4a_image_create(K4A_IMAGE_FORMAT_DEPTH16, 
                     color_width, color_height,
                     color_width * (int)sizeof(uint16_t),
                     &transformed_depth);

    k4a_transformation_depth_image_to_color_camera(transformation,
                                                    depth_image,
                                                    transformed_depth);

    // Asignar arreglo para nube de puntos
    int max_points = color_width * color_height;
    PointXYZRGB* points = (PointXYZRGB*)malloc(sizeof(PointXYZRGB) * max_points);
    int point_count = 0;

    // Obtener buffer de profundidad transformada
    uint16_t* transformed_depth_data = (uint16_t*)k4a_image_get_buffer(transformed_depth);

    // Generar coordenadas XYZ
    float* xyz_buffer = (float*)malloc(color_width * color_height * 3 * sizeof(float));
    k4a_transformation_color_camera_to_world_point(transformation,
                                                     &calibration,
                                                     depth_image,
                                                     color_width * color_height,
                                                     (const k4a_float2_t*)color_buffer,
                                                     xyz_buffer);

    // Iterar por cada píxel
    for (int i = 0; i < color_width * color_height; i++) {
        uint16_t depth = transformed_depth_data[i];

        if (depth > 0 && depth < 65535) {
            points[point_count].x = xyz_buffer[i * 3];
            points[point_count].y = xyz_buffer[i * 3 + 1];
            points[point_count].z = xyz_buffer[i * 3 + 2] / 1000.0f; // mm a metros

            // Añadir color si está disponible
            if (color_buffer != NULL) {
                // Asumiendo formato BGRA
                points[point_count].b = color_buffer[i * 4];
                points[point_count].g = color_buffer[i * 4 + 1];
                points[point_count].r = color_buffer[i * 4 + 2];
            }

            point_count++;
        }
    }

    *points_out = points;
    *point_count_out = point_count;

    // Limpieza
    free(xyz_buffer);
    k4a_image_release(transformed_depth);
    k4a_transformation_destroy(transformation);
}

Este ejemplo demuestra el concepto básico de generación de nubes de puntos: transformar píxeles de profundidad 2D en coordenadas 3D usando los parámetros intrínsecos de calibración de la cámara. La transformación también alinea los datos de profundidad con la perspectiva de la cámara de color, permitiendo nubes de puntos coloreadas donde cada punto 3D tiene un valor RGB asociado.

Acceso a datos IMU

El IMU proporciona datos de movimiento de alta frecuencia que pueden mejorar la precisión del seguimiento y permitir aplicaciones de reconocimiento de gestos. Acceder a los datos del IMU requiere un mecanismo de transmisión separado de los fotogramas de la cámara:

#include <k4a/k4a.h>
#include <stdio.h>
#include <stdlib.h>

void process_imu_sample(k4a_imu_sample_t* sample) {
    printf("Muestra IMU:\n");
    printf("  Acelerómetro: x=%.4f, y=%.4f, z=%.4f (m/s²)\n",
           sample->acc_sample.x, sample->acc_sample.y, sample->acc_sample.z);
    printf("  Giroscopio:  x=%.4f, y=%.4f, z=%.4f (rad/s)\n",
           sample->gyro_sample.x, sample->gyro_sample.y, sample->gyro_sample.z);
    printf("  Marca de tiempo: %.3f s\n", sample->acc_timestamp_usec / 1000000.0);
    printf("  Temperatura: %.2f °C\n", sample->temperature);
}

int main() {
    k4a_device_t device = NULL;
    k4a_device_open(K4A_DEVICE_DEFAULT, &device);

    // Iniciar transmisión IMU (debe iniciarse antes que las cámaras para una sincronización adecuada)
    if (k4a_device_start_imu(device) != K4A_RESULT_SUCCEEDED) {
        printf("Error al iniciar el IMU\n");
        k4a_device_close(device);
        return 1;
    }

    k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
    config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED;
    k4a_device_start_cameras(device, &config);

    // Recopilar muestras del IMU durante 10 segundos
    for (int i = 0; i < 1000; i++) {
        k4a_imu_sample_t sample;
        k4a_wait_result_t result = k4a_device_get_imu_sample(device, &sample, 100);

        if (result == K4A_WAIT_RESULT_SUCCEEDED) {
            process_imu_sample(&sample);
        }
    }

    k4a_device_stop_imu(device);
    k4a_device_stop_cameras(device);
    k4a_device_close(device);

    return 0;
}

El IMU transmite datos a aproximadamente 1.6 kHz, proporcionando actualizaciones de movimiento con mucha más frecuencia que los fotogramas de la cámara. Estos datos de alta frecuencia son valiosos para filtrar las posiciones de la cámara entre fotogramas, detectar movimientos rápidos e integrarse con filtros de Kalman extendidos para un seguimiento robusto.

Sincronización multi-cámara

Configuración de sincronización por cable

Para aplicaciones que requieren múltiples cámaras Femto Bolt—como sistemas de captura volumétrica, escaneo de 360 grados o imágenes con campo de visión extendido—el SDK soporta sincronización por cable a través del conector de sincronización de la cámara. Esto permite que múltiples cámaras capturen fotogramas simultáneamente con precisión de submilisegundos.

Una cámara opera como maestra mientras que las otras operan como subordinadas (esclavas). La cámara maestra genera la señal de sincronización que dispara a todas las cámaras subordinadas para capturar simultáneamente. Conecte las cámaras usando cables TRS de 3.5 mm entre los puertos de sincronización de cada dispositivo:

#include <k4a/k4a.h>
#include <stdio.h>

void configure_master(k4a_device_t device) {
    k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
    config.depth_mode = K4A_DEPTH_MODE_WFOV_UNBINNED;
    config.camera_fps = K4A_FRAMES_PER_SECOND_15;
    config.wired_sync_mode = K4A_WIRED_SYNC_MODE_MASTER;
    config.subordinate_delay_off_master_usec = 0;

    k4a_device_start_cameras(device, &config);
    printf("Cámara configurada como MAESTRA\n");
}

void configure_subordinate(k4a_device_t device) {
    k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
    config.depth_mode = K4A_DEPTH_MODE_WFOV_UNBINNED;
    config.camera_fps = K4A_FRAMES_PER_SECOND_15;
    config.wired_sync_mode = K4A_WIRED_SYNC_MODE_SUBORDINATE;

    // Retardo después del disparo del maestro antes de capturar
    // Ajustar según la longitud del cable y la configuración
    config.subordinate_delay_off_master_usec = 0;

    k4a_device_start_cameras(device, &config);
    printf("Cámara configurada como SUBORDINADA\n");
}

int main() {
    // Abrir primera cámara (maestra)
    k4a_device_t master = NULL;
    k4a_device_open(0, &master);

    // Abrir segunda cámara (subordinada)
    k4a_device_t subordinate = NULL;
    k4a_device_open(1, &subordinate);

    configure_master(master);
    configure_subordinate(subordinate);

    // Ahora ambas cámaras capturarán fotogramas sincronizados
    // El maestro dispara la captura, el subordinado captura después del retardo

    // Limpieza
    k4a_device_stop_cameras(master);
    k4a_device_stop_cameras(subordinate);
    k4a_device_close(master);
    k4a_device_close(subordinate);

    return 0;
}

El parámetro de retardo subordinado compensa los retrasos de propagación de la señal en el cable de sincronización. Para la mayoría de las instalaciones con cables cortos, un retardo cero funciona bien, pero puede que necesite ajustar este valor para una sincronización precisa en configuraciones más grandes.

Sincronización de disparo externo

El Femto Bolt también soporta el modo de disparo externo, donde una señal externa inicia la captura de fotogramas. Esto es esencial para aplicaciones industriales que requieren sincronización con otros equipos, iluminación estroboscópica o secuencias de captura con temporización precisa:

#include <k4a/k4a.h>
#include <stdio.h>

void configure_external_trigger(k4a_device_t device) {
    k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
    config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED;
    config.camera_fps = K4A_FRAMES_PER_SECOND_30;

    // Configurar para modo de disparo externo
    config.wired_sync_mode = K4A_WIRED_SYNC_MODE_SUBORDINATE;
    config.external_sync_mode = true;

    // El disparo externo espera un flanco ascendente para activar la captura
    config.subordinate_delay_off_master_usec = 0;

    k4a_device_start_cameras(device, &config);
    printf("Cámara configurada para modo DISPARO EXTERNO\n");
    printf("Esperando señal de disparo externo...\n");
}

int main() {
    k4a_device_t device = NULL;
    k4a_device_open(K4A_DEVICE_DEFAULT, &device);

    configure_external_trigger(device);

    // Capturar cuadros cuando se active el disparo
    for (int i = 0; i < 10; i++) {
        k4a_capture_t capture = NULL;

        // Esperar hasta 2 segundos por el disparo
        k4a_wait_result_t result = k4a_device_get_capture(device, &capture, 2000);

        if (result == K4A_WAIT_RESULT_SUCCEEDED) {
            printf("Cuadro capturado %d\n", i);
            k4a_capture_release(capture);
        }
    }

    k4a_device_stop_cameras(device);
    k4a_device_close(device);

    return 0;
}

El modo de disparo externo requiere una señal de disparo correctamente formateada en el conector de sincronización. La cámara espera una señal lógica de 3.3V con especificaciones mínimas de ancho de pulso. Consulte la documentación del hardware para los requisitos eléctricos exactos.

Grabación y reproducción

Funcionalidad de grabación MKV

El SDK soporta la grabación de datos de la cámara en archivos MKV (Matroska Video) para análisis, procesamiento o reproducción posteriores. Las grabaciones capturan todos los flujos sincronizados (profundidad, color, IR e IMU) con metadatos completos, permitiendo la reconstrucción total de la sesión de captura:

#include <k4a/k4a.h>
#include <stdio.h>
#include <string.h>

int main() {
    k4a_device_t device = NULL;
    k4a_device_open(K4A_DEVICE_DEFAULT, &device);

    k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
    config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED;
    config.color_resolution = K4A_COLOR_RESOLUTION_720P;
    config.camera_fps = K4A_FRAMES_PER_SECOND_30;
    config.synchronized_images_only = true;

    // Crear configuración de grabación
    k4a_recording_t recording = NULL;
    k4a_recording_configuration_t record_config = {
        .format = K4A_RECORDING_FORMAT_MKV,
        .segment_size = 0,  // 0 = sin segmentación
    };

    // Iniciar grabación en archivo
    const char* filename = "capture_session_001.mkv";
    if (k4a_device_start_recording(device, &record_config, filename) != K4A_RESULT_SUCCEEDED) {
        printf("Error al iniciar la grabación\n");
        k4a_device_close(device);
        return 1;
    }

    printf("Grabando en %s\n", filename);

    // Grabar durante 60 segundos
    for (int frame = 0; frame < 1800; frame++) {  // 30 fps * 60 seg
        k4a_capture_t capture = NULL;
        k4a_wait_result_t result = k4a_device_get_capture(device, &capture, K4A_WAIT_INFINITE);

        if (result == K4A_RESULT_SUCCEEDED) {
            // La captura se añade automáticamente a la grabación
            k4a_capture_release(capture);

            if (frame % 30 == 0) {
                printf("Grabados %d cuadros\n", frame);
            }
        }
    }

    // Detener grabación
    k4a_device_stop_recording(device);
    printf("Grabación completa. Archivo guardado.\n");

    k4a_device_stop_cameras(device);
    k4a_device_close(device);

    return 0;
}

Las grabaciones incluyen automáticamente todos los datos de calibración, asegurando que la reproducción mantenga la precisión espacial completa. El formato MKV es ampliamente compatible y puede procesarse con herramientas de video estándar o con las funciones de reproducción del SDK.

Reproducción y Extracción de Datos

Playing back recorded files is straightforward with the SDK's playback API:

```cpp

include

include

int main() { k4a_playback_t playback = NULL;

// Open recording file
if (k4a_playback_open("capture_session_001.mkv", &playback) != K4A_RESULT_SUCCEEDED) {
    printf("Failed to open recording\n");
    return 1;
}

// Get recording properties
k4a_record_configuration_t record_config;
k4a_playback_get_record_configuration(playback, &record_config);

printf("Recording properties:\n");
printf("  Duration: %.2f seconds\n", k4a_playback_get_duration_count_us(playback) / 1000000.0);
printf("  Depth mode: %d\n", record_config.depth_mode);
printf("  Color resolution: %d\n", record_config.color_resolution);

// Get calibration from recording
k4a_calibration_t calibration;
k4a_playback_get_calibration(playback, &calibration);

// Iterate through all frames
k4a_capture_t capture = NULL;
while (k4a_playback_get_next_capture(playback, &capture) == K4A_RESULT_SUCCEEDED) {
    k4a_image_t depth = k4a_capture_get_depth_image(capture);
    if (depth != NULL) {
        uint64_t timestamp = k4a_image_get_timestamp_usec(depth);
        printf("Frame at %.3f seconds\n", timestamp / 1000000.0);
        k4a_image_release(depth);
    }
    k4a_capture_release(capture);
}

k4a_playback_close(playback);

Preguntas Frecuentes

¿Cuál es el rango máximo de profundidad del Orbbec Femto Bolt?

El Femto Bolt logra una detección de profundidad efectiva desde 0.25 metros hasta 5.46 metros, dependiendo del modo de profundidad seleccionado y las condiciones ambientales. Este rango cubre la mayoría de los escenarios de interacción a escala humana, desde tareas de manipulación robótica de cerca hasta aplicaciones de monitoreo a media distancia. El modo WFOV (Campo de Visión Amplio) optimiza para áreas de cobertura más grandes a costa de algo de precisión, mientras que el modo NFOV (Campo de Visión Estrecho) ofrece mayor exactitud para tareas de inspección más focalizadas.

¿Se puede usar el Femto Bolt en exteriores?

El Femto Bolt está optimizado para entornos interiores, pero puede usarse en semi-exteriores con condiciones de iluminación adecuadas. La luz solar directa intensa puede saturar la iluminación infrarroja que la cámara utiliza para la detección de profundidad, limitando su rendimiento en entornos soleados al aire libre. Sin embargo, áreas exteriores cubiertas, ubicaciones sombreadas o condiciones nubladas suelen permitir un funcionamiento aceptable. Para despliegues permanentes en exteriores, considere una carcasa protectora y controles ambientales.

¿Es el Femto Bolt compatible con ROS (Robot Operating System)?

Sí, el Femto Bolt es compatible con ROS mediante el SDK disponible y wrappers ROS desarrollados por la comunidad. El SDK Azure Kinect que soporta el Femto Bolt tiene opciones de integración con ROS, y la comunidad Orbbec ha desarrollado paquetes ROS adicionales. Esta compatibilidad permite una integración sencilla con flujos de trabajo existentes en desarrollo robótico.

¿Qué tan precisa es la medición de profundidad?

El Femto Bolt alcanza una precisión de profundidad con un error sistemático menor a 11 mm más 0.1% de la distancia medida, con una desviación estándar del error aleatorio mantenida en o por debajo de 17 mm. Este rendimiento cumple con los requisitos de aplicaciones industriales y de investigación exigentes. La precisión real depende del modo de operación, rango, características de la superficie y condiciones ambientales.

¿Se pueden sincronizar múltiples cámaras Femto Bolt?

Sí, el Femto Bolt soporta control de disparo externo que permite una sincronización precisa entre múltiples cámaras. Esta capacidad soporta despliegues en cascada para cobertura extendida, captura multivista para reconstrucción 3D y grabación simultánea desde múltiples puntos de vista para aplicaciones de video volumétrico.

¿Cuál es la diferencia entre los modos WFOV y NFOV?

El modo WFOV (Campo de Visión Amplio) captura profundidad a una resolución de 1024x1024 y 15 cuadros por segundo, proporcionando una cobertura horizontal y vertical de 120°, ideal para aplicaciones de áreas grandes. El modo NFOV (Campo de Visión Estrecho) ofrece resolución de 640x576 a 30 cuadros por segundo con cobertura horizontal de 75° y vertical de 65°, adecuado para aplicaciones que requieren un examen enfocado con tasas de cuadros más altas.

¿El Femto Bolt requiere iluminación especial?

El Femto Bolt utiliza su propia iluminación infrarroja para la detección de profundidad, por lo que no requiere iluminación externa específica para las mediciones de profundidad. Sin embargo, la cámara RGB funciona como una cámara convencional y se beneficia de una iluminación adecuada para la captura de color. Para precisión en la profundidad, evite superficies altamente reflectantes y materiales extremadamente oscuros que puedan afectar el retorno de la señal infrarroja.

¿Qué lenguajes de programación son compatibles para el desarrollo con Femto Bolt?

El Femto Bolt soporta desarrollo en múltiples lenguajes mediante varios SDKs. El SDK principal en C/C++ ofrece la funcionalidad más completa a través de la API Azure Kinect y el K4A Wrapper. Los desarrolladores en Python pueden usar los paquetes pyk4a o azure-kinect-python. Existen enlaces comunitarios adicionales para C#, Unity y otros lenguajes.

Conclusión

El Orbbec Femto Bolt transforma la avanzada tecnología de visión 3D de equipos especializados costosos en una capacidad accesible para desarrolladores e integradores en prácticamente todas las industrias. Su combinación excepcional de detección de profundidad TOF de alta precisión, imagen RGB 4K, factor de forma notablemente compacto y compatibilidad total con Azure Kinect crea una plataforma extraordinariamente versátil adecuada para aplicaciones que van desde la sofisticada selección robótica en contenedores hasta la captura de video volumétrico, desde sistemas detallados de inspección hasta experiencias inmersivas de AR.

La amplia gama de posibilidades de desarrollo —que abarca robótica, visión por computadora, AR/VR, logística, salud e investigación— demuestra la notable versatilidad de la tecnología. Prácticamente todas las industrias pueden encontrar un valor extraordinario en la capacidad de la cámara para capturar información tridimensional precisa que permite la automatización, el análisis y la interacción que antes eran inviables debido a los altos costos o la complejidad.

La implementación exitosa requiere una comprensión cuidadosa de los requisitos ambientales, consideraciones de integración y limitaciones de rendimiento. Sin embargo, para aplicaciones que realmente se alinean con sus capacidades excepcionales, el Femto Bolt ofrece una base excelente para soluciones innovadoras de visión 3D.


Esta guía completa de desarrollo cubre la configuración del SDK Orbbec Femto Bolt, tutoriales de programación y ejemplos de código. Para especificaciones detalladas del producto e información de compra, visita la página del producto Orbbec Femto Bolt en OpenELAB.

¿Interesado en aprender más sobre la tecnología de cámaras ToF? Explora la amplia colección de OpenELAB de cámaras TOF y cámaras de profundidad para más opciones.

¿Buscas ejemplos de aplicaciones? Consulta nuestra Guía de aplicaciones Orbbec Femto Bolt para descubrir casos de uso específicos de la industria y conocimientos sobre implementación.

¿Listo para empezar a desarrollar? Explora los recursos de desarrollo de OpenELAB para documentación del SDK, ejemplos prácticos de código y tutoriales detallados de integración que acelerarán el desarrollo de tu proyecto de visión 3D.

Aprende más sobre la tecnología Time of Flight en Wikipedia y participa en discusiones en Reddit sobre robótica y aplicaciones de cámaras de profundidad.

Comprar: OpenELAB

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados *

Barra lateral

Categorías del blog
Última publicación
Etiquetas del blog

Regístrate en nuestro boletín

Obtén la información más reciente sobre nuestros productos y ofertas especiales.

Website Feedback

Help us improve OpenELAB

Found a website issue or have an idea? Tell us what would make your experience better.