Metadata-Version: 2.2
Name: imprintsdk
Version: 0.2.1
Summary: macOS EVT20 event camera SDK with a single OpenCV viewer
Classifier: Operating System :: MacOS :: MacOS X
Requires-Python: >=3.8
Requires-Dist: numpy<2,>=1.24; python_version < "3.9"
Requires-Dist: numpy>=1.26; python_version >= "3.9"
Requires-Dist: opencv-python<6,>=4.10
Description-Content-Type: text/markdown

# imprintsdk 使用说明（仅限 macOS）

`imprintsdk 0.2.1` 是仅适用于 macOS 的 EVT20 事件相机 Python SDK，公开接口只有 `gui()`。运行后只打开一个 OpenCV 图像窗口，显示事件图像和每秒事件数 `Events/s`，没有控制面板，不显示 FPS 或累计事件数。

## 1. 安装

需要 **macOS、Apple Silicon（M 系列芯片）和 Python 3.8+**，并需要可用的桌面显示环境，以及通过 USB 串口连接的 EVT20 事件相机。

```bash
python -m pip install --upgrade "imprintsdk==0.2.1"
```

pip 会自动下载并安装以下依赖，无需单独安装 OpenCV：

- `opencv-python`：图像处理和窗口显示。
- `numpy`：事件数组处理。

本包只支持 macOS，不支持 Windows 或 Linux。PyPI 仅发布 macOS wheel，不发布源码安装包。安装包适配 **Apple Silicon（arm64）**，同一个 wheel 支持多个 Python 版本，无需按 Python 小版本选择安装包。当前验证范围为 Python 3.8–3.14；Intel Mac 暂未提供对应的发布包。

建议使用独立虚拟环境，避免和其他项目安装的 OpenCV 发行包冲突。同一环境应使用带 GUI 功能的 `opencv-python`；`opencv-python-headless` 不具备窗口功能。

### 从本地 wheel 安装

在尚未上传 PyPI 或离线分发 SDK wheel 时，进入 wheel 所在目录：

```bash
python -m pip install --find-links . "imprintsdk==0.2.1"
```

本地 wheel 安装也会自动下载依赖；完全离线安装需要提前准备 OpenCV 和 NumPy 的匹配 wheel。SDK 的 C++ 核心以普通 `.dylib` 动态库包含在 wheel 中，由 Python 标准库 `ctypes` 调用，不依赖某个 Python 小版本的扩展 ABI，不需要额外复制 `libevtcap`，也不依赖开发仓库的 `build/` 目录。

## 2. 命令行启动

### 自动选择端口

macOS 只检测到一个 USB 串口设备时，直接运行：

```bash
imprintsdk
```

自动检测范围为 `/dev/cu.usbmodem*` 和 `/dev/cu.usbserial*`。这只是串口枚举，不会验证设备型号；如果还连接了其他串口设备，请明确指定相机端口。

也可以使用等效入口，避免终端找不到 `imprintsdk` 命令：

```bash
python -m imprintsdk
```

### 明确指定端口

下面的端口名称是示例，请替换成实际设备端口。

```bash
ls /dev/cu.usbmodem* /dev/cu.usbserial* 2>/dev/null
python -m imprintsdk --device /dev/cu.usbmodemYOUR_DEVICE
```

优先使用 `/dev/cu.*`。传入 `/dev/tty.*` 时，SDK 会在对应 `/dev/cu.*` 存在的情况下自动切换。

### 查看参数

```bash
python -m imprintsdk --help
```

| 命令行参数 | 默认值 | 含义 |
| --- | --- | --- |
| `--device` | 自动选择 | 相机串口；多个设备时必须指定 |
| `--baudrate` | `115200` | 串口配置波特率，按设备要求设置 |
| `--width` | `320` | 传感器宽度，范围 1–2048 |
| `--height` | `320` | 传感器高度，范围 1–2048 |
| `--display-fps` | `60` | 界面刷新上限；必须大于 0，不改变相机采集速率 |

例如：

```bash
python -m imprintsdk --device /dev/cu.usbmodemYOUR_DEVICE --width 320 --height 320 --display-fps 60
```

## 3. 在 Python 中调用

创建 `view_camera.py`：

```python
from imprintsdk import gui

if __name__ == "__main__":
    gui(device="/dev/cu.usbmodemYOUR_DEVICE")
```

运行：

```bash
python view_camera.py
```

macOS 只有一个相机串口时，也可以省略端口：

```python
from imprintsdk import gui

gui()
```

唯一公开函数的完整签名：

```text
gui(device=None, *, baudrate=115200, width=320, height=320, display_fps=60)
```

`gui()` 会阻塞到窗口退出，必须在 Python 主线程调用。正常关闭后返回 `None`；参数错误会抛出 `ValueError`，打开设备、启动采集或资源清理失败会抛出 `RuntimeError`。命令行入口会打印错误并以非零状态退出。

## 4. 窗口显示与退出

启动后自动开启补光灯并开始采集，只显示一个名为 `Imprint SDK - Events` 的 OpenCV 窗口。

- **红色像素：** 正极性事件。
- **蓝色像素：** 负极性事件。
- **`Events: 12,000/s`：** 主机最近约一秒内成功解码的事件速率；一个事件是一个像素的一次变化记录。该数值不代表整帧图像数量。

显示窗口会把一批事件合并绘制。C++ 后台线程独立采集，界面刷新上限和事件速率互相独立；窗口只展示最新可用数据，不执行数据录制或完整历史回放。

以下任一操作都可以退出：

1. 点击图像窗口的关闭按钮。
2. 图像窗口获得焦点后按 `q` 或 `Esc`。
3. 在启动程序的终端按 `Ctrl+C`。

退出时会依次尝试关灯、停止采集、关闭串口和销毁窗口。即使前一步出现异常，也会继续尝试后续清理。

## 5. 常见问题

**`Specify device explicitly`**

未检测到串口，或同时检测到多个串口。检查 USB 连接，并使用 `--device` 指定相机的实际端口。重新插拔或更换相机后，端口名可能变化。

**`Cannot open ...`**

检查端口是否存在、是否被其他采集程序占用，以及当前用户是否有串口访问权限。优先使用 `/dev/cu.*`。

**无法创建 OpenCV 窗口 / `The function is not implemented`**

确认在有桌面的会话中运行，并且当前虚拟环境安装的是 `opencv-python`。无桌面的 SSH 会话或 headless OpenCV 不满足这个 GUI 的运行条件。

**`No matching distribution found`**

确认使用 macOS Apple Silicon 上的原生 Python，而不是 Rosetta 下的 x86_64 Python，并升级 pip。同一个发布包适用于 Python 3.8+，无需更换到指定小版本。当前没有 Windows、Linux 或 Intel Mac 安装包，也不会回退到源码安装。

**窗口黑屏或事件数很低**

事件相机输出的是亮度变化。先让相机观察有运动或亮度变化的场景，再查看事件数；同时确认终端没有开灯或启动采集失败的提示。

## 6. 从源码构建与开发

源码构建也仅支持 macOS。在项目根目录，使用 Python 3.8+ 并安装好 Xcode Command Line Tools（包含 C++17 编译器）后运行；构建工具会自动准备 CMake；构建不需要 Python 开发头文件或 pybind11：

```bash
uv build --wheel
```

macOS Apple Silicon 发布构建只需执行一次：

```bash
python tools/build_macos_wheels.py
```

安装生成的 wheel：

```bash
python -m pip install --find-links dist/release "imprintsdk==0.2.1"
```

开发目录中仍可使用原来的脚本入口，它会调用同一个单窗口 GUI：

```bash
uv run tools/consumer/visualize_events.py --device /dev/cu.usbmodemYOUR_DEVICE
```

安装 wheel 后运行 GUI 生命周期回归检查：

```bash
python -m unittest discover -s test -p test_gui.py -v
```

项目原有的 C++ API 与底层构建说明保留在 `README.md` 中。本文件描述的是 `imprintsdk 0.2.1` 的 Python 使用接口；内部原生模块不属于稳定公开 API。

维护者发布前，生成单个 `py3-none-macosx_*_arm64.whl`，并检查包说明。`py3-none` 表示不绑定 CPython 小版本，macOS 和 CPU 架构仍有平台要求：

```bash
python tools/build_macos_wheels.py
uvx twine check dist/release/imprintsdk-0.2.1-*.whl
python tools/publish_pypi.py
```

发布脚本只会选择当前版本的 macOS wheel，不会上传源码包或其他平台的 wheel。最后一步需要有 `imprintsdk` 发布权限的 PyPI API Token。脚本在本机终端隐藏输入 Token，将其仅传给上传进程，不写入源码或配置文件。请勿把 Token 填进 README 或提交到 Git。
