Metadata-Version: 2.4
Name: hex_dora_node_camera
Version: 0.0.1a5
Summary: Dora Node for using Hex Camera
Author-email: Dong Zhaorui <847235539@qq.com>
License-Expression: Apache-2.0
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: dora-rs>=0.3.9
Requires-Dist: hex-driver-camera<0.1.0,>=0.0.0
Requires-Dist: hex-util-robot<0.1.0,>=0.0.0
Provides-Extra: berxel
Requires-Dist: berxel_py_wrapper>=2.0.182; extra == "berxel"
Provides-Extra: realsense
Requires-Dist: pyrealsense2>=2.56.5.9235; extra == "realsense"
Provides-Extra: all
Requires-Dist: berxel_py_wrapper>=2.0.182; extra == "all"
Requires-Dist: pyrealsense2>=2.56.5.9235; extra == "all"
Dynamic: license-file

# hex_dora_node_camera

Dora nodes for capturing and viewing camera images. Supports multiple camera backends including USB cameras, Intel RealSense, Berxel depth cameras, and a dummy camera for testing.

## Nodes

| Node | Description | Inputs | Outputs |
| --- | --- | --- | --- |
| `hex-dora-node-usb` | USB camera capture (V4L2) | `tick` | `color` |
| `hex-dora-node-realsense` | Intel RealSense depth camera capture | `tick` | `color`, `depth` |
| `hex-dora-node-berxel` | Berxel depth camera capture | `tick` | `color`, `depth` |
| `hex-dora-node-dummy` | Dummy camera for testing (generates synthetic frames) | `tick` | `color` |
| `hex-dora-node-test-usb` | OpenCV window viewer for USB color stream | `tick`, `color` | - |
| `hex-dora-node-test-realsense` | OpenCV window viewer for RealSense color/depth streams | `tick`, `color`, `depth` | - |
| `hex-dora-node-test-berxel` | OpenCV window viewer for Berxel color/depth streams | `tick`, `color`, `depth` | - |
| `hex-dora-node-test-dummy` | OpenCV window viewer for dummy color stream with optional timestamp overlay | `tick`, `color` | - |

## Installation

```bash
# Base (includes usb, dummy, and test nodes)
pip install hex_dora_node_camera

# With Berxel support
pip install hex_dora_node_camera[berxel]

# With RealSense support
pip install hex_dora_node_camera[realsense]

# All backends
pip install hex_dora_node_camera[all]
```

## YAML Examples

### USB Camera

```yaml
nodes:
  - id: cam_usb
    build: pip install hex_dora_node_camera
    path: hex-dora-node-usb
    inputs:
      tick: dora/timer/millis/2
    outputs:
      - color
    env:
      NODE_NAME: cam_usb
      # base
      FRAME_RATE: 30
      HEIGHT: 480
      WIDTH: 640
      CAM_BUFFER_SIZE: 8
      SEN_TS: True
      # usb
      CAM_PATH: /dev/video0
      EXPOSURE: 0
      TEMPERATURE: 0
      # encoding
      COLOR_ENCODING: mjpg # bgr8 or mjpg

  - id: test_usb
    build: pip install hex_dora_node_camera
    path: hex-dora-node-test-usb
    inputs:
      tick: dora/timer/millis/2
      color: cam_usb/color
    env:
      NODE_NAME: test_usb
```

### Intel RealSense

```yaml
nodes:
  - id: cam_realsense
    build: pip install hex_dora_node_camera[realsense]
    path: hex-dora-node-realsense
    inputs:
      tick: dora/timer/millis/2
    outputs:
      - color
      - depth
    env:
      NODE_NAME: cam_realsense
      # base
      FRAME_RATE: 30
      HEIGHT: 480
      WIDTH: 640
      CAM_BUFFER_SIZE: 8
      SEN_TS: True
      # realsense
      SERIAL_NUMBER: b021222071077
      # encoding
      COLOR_ENCODING: bgr8 # bgr8 or mjpg
      DEPTH_ENCODING: uint16 # uint16 or png

  - id: test_realsense
    build: pip install hex_dora_node_camera
    path: hex-dora-node-test-realsense
    inputs:
      tick: dora/timer/millis/2
      color: cam_realsense/color
      depth: cam_realsense/depth
    env:
      NODE_NAME: test_realsense
```

### Berxel Depth Camera

```yaml
nodes:
  - id: cam_berxel
    build: pip install hex_dora_node_camera[berxel]
    path: hex-dora-node-berxel
    inputs:
      tick: dora/timer/millis/2
    outputs:
      - color
      - depth
    env:
      NODE_NAME: cam_berxel
      # base
      FRAME_RATE: 30
      HEIGHT: 400
      WIDTH: 640
      CAM_BUFFER_SIZE: 8
      SEN_TS: True
      # berxel
      SERIAL_NUMBER: bP050HYX5410E1A001
      EXPOSURE: 10000
      GAIN: 100
      # encoding
      COLOR_ENCODING: bgr8 # bgr8 or mjpg
      DEPTH_ENCODING: uint16 # uint16 or mjpg

  - id: test_berxel
    build: pip install hex_dora_node_camera
    path: hex-dora-node-test-berxel
    inputs:
      tick: dora/timer/millis/2
      color: cam_berxel/color
      depth: cam_berxel/depth
    env:
      NODE_NAME: test_berxel
```

### Dummy Camera (Testing)

```yaml
nodes:
  - id: cam_dummy
    build: pip install hex_dora_node_camera
    path: hex-dora-node-dummy
    inputs:
      tick: dora/timer/millis/2
    outputs:
      - color
    env:
      NODE_NAME: cam_dummy
      # base
      FRAME_RATE: 30
      HEIGHT: 480
      WIDTH: 640
      CAM_BUFFER_SIZE: 8
      SEN_TS: True
      # encoding
      COLOR_ENCODING: bgr8 # bgr8 or mjpg

  - id: test_dummy
    build: pip install hex_dora_node_camera
    path: hex-dora-node-test-dummy
    inputs:
      tick: dora/timer/millis/2
      color: cam_dummy/color
    env:
      NODE_NAME: test_dummy
      SHOW_COLOR_TS: True
```

## Inputs

### Camera Nodes (`usb` / `realsense` / `berxel` / `dummy`)

| Input | Type | Description |
| --- | --- | --- |
| `tick` | `dora/timer/millis/*` | Timer tick to trigger frame capture |

### Test Nodes (`test-usb` / `test-dummy`)

| Input | Type | Description |
| --- | --- | --- |
| `tick` | `dora/timer/millis/*` | Timer tick to refresh display |
| `color` | Arrow array | Color image from a camera node |

### Test Nodes (`test-realsense` / `test-berxel`)

| Input | Type | Description |
| --- | --- | --- |
| `tick` | `dora/timer/millis/*` | Timer tick to refresh display |
| `color` | Arrow array | Color image from a camera node |
| `depth` | Arrow array | Depth image from a depth camera node |

## Outputs

### `color`

Arrow array containing the color image.

```python
color_data: UInt8Array  # pa.array(img.ravel()) or pa.array(jpeg_bytes)
metadata = {
    "width": int,       # e.g. 640
    "height": int,      # e.g. 480
    "encoding": str,    # "bgr8" or "mjpg"
    "primitive": "image",
}
```

### `depth`

Arrow array containing the depth image (only for `realsense` and `berxel`).

```python
depth_data: UInt16Array  # pa.array(depth.ravel()) or pa.array(png_bytes)
metadata = {
    "width": int,       # e.g. 640
    "height": int,      # e.g. 480
    "encoding": str,    # "uint16", "png" (realsense) or "mjpg" (berxel)
    "primitive": "image",
}
```

## Environment Variables

### Common (all camera nodes)

| Variable | Type | Default | Description |
| --- | --- | --- | --- |
| `NODE_NAME` | `str` | `""` | Dora node name |
| `FRAME_RATE` | `int` | `30` | Camera frame rate |
| `HEIGHT` | `int` | `480` (`400` for berxel) | Image height in pixels |
| `WIDTH` | `int` | `640` | Image width in pixels |
| `CAM_BUFFER_SIZE` | `int` | `8` | Camera internal buffer size |
| `SEN_TS` | `bool` | `True` | Use sensor timestamp |
| `COLOR_ENCODING` | `str` | `bgr8` | Color encoding: `bgr8` or `mjpg` |

### USB Camera

| Variable | Type | Default | Description |
| --- | --- | --- | --- |
| `CAM_PATH` | `str` | `/dev/video0` | V4L2 device path |
| `EXPOSURE` | `int` | `100` | Camera exposure value (0 = auto) |
| `TEMPERATURE` | `int` | `4000` | White balance temperature (0 = auto) |

### Intel RealSense

| Variable | Type | Default | Description |
| --- | --- | --- | --- |
| `SERIAL_NUMBER` | `str` | (required) | Device serial number (prefix with `b`) |
| `DEPTH_ENCODING` | `str` | `uint16` | Depth encoding: `uint16` or `png` |

### Berxel

| Variable | Type | Default | Description |
| --- | --- | --- | --- |
| `SERIAL_NUMBER` | `str` | (required) | Device serial number (prefix with `b`) |
| `EXPOSURE` | `int` | `10000` | Camera exposure value |
| `GAIN` | `int` | `100` | Camera gain value |
| `DEPTH_ENCODING` | `str` | `uint16` | Depth encoding: `uint16` or `mjpg` |

### Test Dummy

| Variable | Type | Default | Description |
| --- | --- | --- | --- |
| `NODE_NAME` | `str` | `""` | Dora node name |
| `SHOW_COLOR_TS` | `bool` | `False` | Overlay timestamp text on color image |

## License

This project is licensed under Apache-2.0.
