Metadata-Version: 2.1
Name: ydl2
Version: 0.3.2
Summary: OpenCV 轻量扩展(Unicode 路径/HALCON 缩放/形状匹配)，可选 UNet 分割训练与推理
Author-email: 无敌的杨 <ydl779762225@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/CiweiWenruo/ydl2
Keywords: opencv,cv2,image,halcon,scale_image,segmentation,unet,pytorch
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.21
Requires-Dist: opencv-python>=4.6
Provides-Extra: cnn
Requires-Dist: torch>=2.0; extra == "cnn"
Requires-Dist: torchvision; extra == "cnn"
Requires-Dist: segmentation-models-pytorch; extra == "cnn"
Requires-Dist: pyyaml; extra == "cnn"
Requires-Dist: addict; extra == "cnn"
Requires-Dist: tqdm; extra == "cnn"
Requires-Dist: pillow; extra == "cnn"
Provides-Extra: cnn-onnx
Requires-Dist: onnx; extra == "cnn-onnx"
Requires-Dist: onnxruntime; extra == "cnn-onnx"

# ydl2

`ydl2` 是对 OpenCV 的轻量补充：解决 **Windows 中文路径** 读写问题，提供与 **HALCON** 语义一致的灰度缩放算子，以及基于 HALCON 的**形状模板匹配**封装。

## 安装

```bash
# 核心(轻量，仅 numpy + opencv)：中文路径、HALCON 缩放、形状匹配
pip install ydl2

# 额外解锁 UNet 分割训练与推理(会安装 torch 等)
pip install "ydl2[cnn]"

# 再额外需要 ONNX 导出/推理时
pip install "ydl2[cnn,cnn-onnx]"
# GPU 加速 ORT 推理
pip install onnxruntime-gpu
```

`pip install ydl2` 只有 HALCON / OpenCV 相关功能；只有 `pip install ydl2[cnn]` 之后，
`ydl2.cnn`（UNet 分割训练/推理）才可用。

## 快速使用

### Unicode 路径 & 灰度缩放

```python
import ydl2

# Unicode 路径读写（Windows 中文路径）
img = ydl2.imread(r"D:\图片\测试.png")
ydl2.imwrite(r"D:\图片\输出.png", img)

# HALCON 等价算子
stretched = ydl2.scale_image_max(img)
inverted  = ydl2.scale_image(img, -1.0, 255.0)
mapped    = ydl2.scale_image_range(img, 100, 200)
```

### 形状模板匹配

```python
import ydl2, cv2

model  = ydl2.read_shape_model(r"model.yyds")
mat    = cv2.imread(r"image.jpg")
b, g, r = cv2.split(mat)
handle = ydl2.any_to_tiyoo(r, g, b)

results = ydl2.find_shape_model(handle, model)
for res in results:
    print(res['row'], res['col'], res['score'])

# 后续帧原地更新（零内存分配）
handle = ydl2.any_to_tiyoo(r, g, b, handle=handle)

ydl2.clear_image(handle)
ydl2.clear_shape_model(model)
```

## API

| 函数 | 说明 |
|------|------|
| `imread` / `imwrite` / `imshow` | 支持中文路径的读写与显示 |
| `scale_image_max` | 每通道 min/max 拉伸到 0–255 |
| `scale_image` | `g' = g * Mult + Add` |
| `scale_image_range` | 区间线性映射 |
| `any_to_tiyoo` | numpy 数组 → Halcon 图像句柄（创建或原地更新） |
| `tiyoo_to_any` | Halcon 图像句柄 → numpy 数组 |
| `read_image` / `write_image` / `clear_image` | Halcon 图像文件读写与释放 |
| `read_shape_model` / `clear_shape_model` | 加载 / 释放 Halcon 模板文件 |
| `find_shape_model` | 形状模板匹配，返回 `[{'row', 'col', 'angle', 'score'}]` |

## 分割(CNN)：UNet 训练与推理

`ydl2.cnn` 提供 YOLO 风格的极简分割接口（基于 PyTorch + segmentation-models-pytorch 的 UNet）。
需先安装 `pip install ydl2[cnn]`；未安装时导入会给出中文安装提示，不影响核心包。

### 训练

```python
from ydl2.cnn import Seg

# 用配置文件训练
Seg("cfg.yaml").train()

# 指定输出目录 / 断点续训
Seg("cfg.yaml").train(work_dir="runs/exp1")
Seg("cfg.yaml").train(resume="runs/exp1/checkpoints/last.pth")
```

配置文件示例见下方「训练配置」章节。训练已内置深度优化：
AMP(bf16/fp16 自动选择)、channels_last、梯度累积、LR 线性预热、
权重 EMA、CUDA 流预取、GPU 端流式验证指标等，通过 `runner` / `hooks` 字段开关。

### 推理（PyTorch 后端）

```python
from ydl2.cnn import Seg

m = Seg("best.pth", config="cfg.yaml", device="cuda")
m.warmup()                                           # 预热，消除首图冷启动

mask = m.predict("a.png")                            # 返回 mask[H,W] int64
vis, mask = m.predict("a.png", visualize=True)       # 叠加可视化 + mask
results = m.predict_batch(["a.png", "b.png"])        # 批量推理，返回 [(mask, RGB), ...]

m.release()                                          # 释放显存；也支持 with Seg(...) as m:
```

推理已启用 channels_last、`inference_mode`、autocast(bf16/fp16)、GPU 端最近邻还原尺寸等优化。

#### 可选：torch.compile 长推理加速

```python
# 需要 triton（Windows: pip install triton-windows）
# 适合固定尺寸、进程常驻、长时间连续推理；首次前向触发编译（~30 s），建议配合 warmup
m = Seg("best.pth", config="cfg.yaml", compile=True)
m.warmup()   # warmup 同时触发编译，之后推理即为稳态
```

### ONNX 导出 & ORT 推理

```python
# 需先安装：pip install "ydl2[cnn,cnn-onnx]"
# GPU 加速：pip install onnxruntime-gpu

# 1. 从 pth 导出 ONNX（嵌入 mean/std/类别名/输入尺寸等 meta）
Seg("best.pth", config="cfg.yaml").export("onnx", "model.onnx")
Seg("best.pth", config="cfg.yaml").export("onnx", "model.onnx", dynamic=True)  # 动态 batch

# 2. 加载 .onnx 走 ORT 推理（接口与 pth 完全一致）
m = Seg("model.onnx", config="cfg.yaml")   # 自动选 CUDA EP；无 GPU 则 CPU
m.warmup()
mask = m.predict("a.png")
vis, mask = m.predict("a.png", visualize=True)
m.release()
```

### 预热 / 保温 / 释放

针对「进程常驻但久未推理后，第一张图明显变慢（GPU 空闲自动降频）」的工业场景：

```python
# batch_size 应与线上推理保持一致，让 cudnn autotune / compile 图命中同一缓存
m.warmup(n=3, batch_size=1)   # 单图推理
m.warmup(n=3, batch_size=4)   # predict_batch(4 张) 时用 batch_size=4

# 保温：低功耗脉冲（默认）
m.keep_warm(True, mode="pulse", interval=30, batch_size=1)
# 保温：锁频（首图最快、功耗较高，需要管理员权限锁 GPU 时钟）
m.keep_warm(True, mode="lock")
m.keep_warm(False)            # 关闭保温

m.release()                   # 停止保温线程并释放资源
```

保温设计要点：
- 保温线程与推理共享同一把锁，脉冲用「非阻塞拿锁」，真实推理在跑时直接跳过本次脉冲，绝不阻塞业务；
- 刚推理过的活跃期内不脉冲，省电；
- `pulse`：每 `interval` 秒一次极短前向，增量功耗小；`lock`：`nvidia-smi` 锁时钟，首图最快，功耗高，锁频失败自动回退高频脉冲。

### 训练配置示例

```yaml
work_dir: runs/bubble_seg

runner:
  max_epochs: 50
  device: cuda
  channels_last: true
  accumulate: 1         # 显存不足时调大
  compile: false        # Windows 需先 pip install triton-windows

model:
  type: Segmentor
  backbone:
    type: SMPUnetBackbone
    encoder_name: resnet34
    encoder_weights: imagenet
    in_channels: 3
    num_classes: 2      # 背景 + 1 类前景
  head:
    type: SegIdentityHead
  loss:
    type: CombinedLoss
    losses:
      - type: CrossEntropyLoss
        ignore_index: 255
      - type: DiceLoss
        ignore_index: 255
        exclude_background: true

optimizer:
  type: AdamW
  lr: 0.0005
  weight_decay: 0.0001

lr_scheduler:
  type: CosineAnnealingLR
  T_max: 50

data:
  samples_per_gpu: 8
  workers_per_gpu: 0
  auto_class_weights: true       # 自动按像素频率算 CE 权重，应对类别不均衡
  background_class_index: 0
  background_max_weight: 0.1
  train:
    type: SegFolderDataset
    image_dir: data/images
    mask_dir: data/masks
    num_classes: 2
    pipeline:
      - type: SegResize
        size: 512
      - type: SegRandomHorizontalFlip
        p: 0.5
      - type: SegToTensor
      - type: SegNormalize
        mean: [0.485, 0.456, 0.406]
        std:  [0.229, 0.224, 0.225]
  val:
    type: SegFolderDataset
    image_dir: data/val_images
    mask_dir: data/val_masks
    num_classes: 2
    pipeline:
      - type: SegResize
        size: 512
      - type: SegToTensor
      - type: SegNormalize
        mean: [0.485, 0.456, 0.406]
        std:  [0.229, 0.224, 0.225]

hooks:
  - type: LoggerHook
    interval: 10
    tensorboard: false
    progress_bar: true
  - type: AMPHook
  - type: LrSchedulerHook
    by_epoch: true
    warmup_iters: 20
    warmup_ratio: 0.1
  - type: EMAHook
    decay: 0.9999
    tau: 100
  - type: EvalHook
    interval: 1
  - type: CheckpointHook
    interval: 1
    best_metric: mIoU
    rule: max
    save_optimizer: false
    max_keep: 3
```

掩码格式：PNG 文件，像素值 = 类别索引（0 背景、1/2/… 前景），不支持 RGB 调色板掩码（请提前转为灰度索引图）。

## 依赖

- Python >= 3.10
- numpy >= 1.21
- opencv-python >= 4.6
- 分割功能（可选 `[cnn]`）：torch >= 2.0、torchvision、segmentation-models-pytorch、pyyaml、addict、tqdm、pillow
- ONNX（可选 `[cnn-onnx]`）：onnx、onnxruntime

## 链接

- 仓库：<https://github.com/CiweiWenruo/ydl2>
