Koharu YOLO26s (ONNX)
ONNX export of mayocream/koharu-yolo26s,
a comic-page instance-segmentation model. Four classes, boxes and masks:
| ID | Class |
|---|---|
| 0 | frame |
| 1 | dialogue_text |
| 2 | balloon |
| 3 | onomatopoeia_text |
This repository contains only the exported graph. Weights, training details and evaluation live in the source repository.
Graph
IN images float32 [batch, 3, height, width]
OUT output0 float32 [batch, instances, 38]
OUT output1 float32 [batch, 32, height/4, width/4]
output0 rows are x1 y1 x2 y2 confidence class_id followed by 32 mask
coefficients, in input-image pixels, sorted by confidence. output1 holds the
mask prototypes.
The head is end-to-end (end2end: True), so no NMS is applied and none is
needed — but see the deduplication note below.
Shapes are dynamic. Height and width must be multiples of the stride (32).
Inference
import numpy as np
import onnxruntime as ort
from PIL import Image
IMGSZ, STRIDE, CONF = 1280, 32, 0.25
image = Image.open("page.jpg").convert("RGB")
width, height = image.size
scale = IMGSZ / max(width, height)
new_w, new_h = round(width * scale), round(height * scale)
out_w = int(np.ceil(new_w / STRIDE) * STRIDE)
out_h = int(np.ceil(new_h / STRIDE) * STRIDE)
canvas = np.full((out_h, out_w, 3), 114, dtype=np.uint8)
pad_x, pad_y = (out_w - new_w) // 2, (out_h - new_h) // 2
canvas[pad_y:pad_y + new_h, pad_x:pad_x + new_w] = np.asarray(
image.resize((new_w, new_h), Image.BILINEAR)
)
batch = canvas.astype(np.float32).transpose(2, 0, 1)[None] / 255.0
session = ort.InferenceSession("koharu-yolo26s.onnx", providers=["CPUExecutionProvider"])
detections, protos = session.run(None, {"images": batch})
names = {0: "frame", 1: "dialogue_text", 2: "balloon", 3: "onomatopoeia_text"}
flat = protos[0].reshape(32, -1)
for row in detections[0][detections[0][:, 4] >= CONF]:
box = [(row[0] - pad_x) / scale, (row[1] - pad_y) / scale,
(row[2] - pad_x) / scale, (row[3] - pad_y) / scale]
mask = 1 / (1 + np.exp(-(row[6:] @ flat).reshape(protos.shape[2], protos.shape[3])))
print(names[int(row[5])], round(float(row[4]), 3), [round(v, 1) for v in box],
"mask px", int((mask > 0.5).sum()))
Crop each mask to its own box before use; the prototype basis is shared across instances, so an uncropped mask can carry probability mass from elsewhere on the page.
Notes for consumers
Deduplicate per class. The end-to-end head emits the same instance more than once. Measured over 12 pages: 3 duplicates in 144 instances at confidence 0.25, 12 in 166 at 0.10. Pairs of same-class boxes above IoU 0.7 are duplicates, not separate regions. This is a property of the head, not of the export — the PyTorch checkpoint produces the identical duplicates.
Padding changes results. Square 1280x1280 padding and stride-multiple
rectangular padding are not interchangeable. Same graph, same pages, square
versus rectangular: 109 matched instances, 2 only in square, 5 only in
rectangular, box IoU as low as 0.900, and confidence differences averaging 0.064
with a maximum of 0.634. Rectangular padding matches the Ultralytics predict
convention and is ~24% faster (445 ms versus 582 ms per page, ONNX Runtime CPU,
M1). Pick one and keep it.
Execution provider changes results near the threshold. CoreML claims 406 of 435 nodes and agrees on geometry (box IoU minimum 0.995), but confidences shift by up to 0.141 and two extra instances appeared across 130. Where reproducibility matters more than latency, pin the CPU provider.
Export
model.export(format="onnx", imgsz=1280, opset=17, dynamic=True, simplify=False)
Exported with Ultralytics 8.4.112, PyTorch 2.13.0, onnx 1.22.0.
| File | SHA-256 |
|---|---|
koharu-yolo26s.onnx |
25a0b06c4ce7ee7c247068a6b3633f98d0f5e913c26ef1cbd06bec3407e914f4 |
Export fidelity
The export was checked against the PyTorch checkpoint on byte-identical input,
comparing decoded instances rather than raw tensors — output0 rows are
confidence-sorted, so a single flipped score permutes every row below it and
makes element-wise comparison meaningless.
| Confidence | Instances (torch / ONNX) | Matched | Box IoU (min) | Mask IoU (min) | Max abs confidence delta |
|---|---|---|---|---|---|
| 0.25 | 144 / 144 | 144 | 1.000 | 1.000 | 6e-05 |
| 0.10 | 166 / 166 | 166 | 1.000 | 1.000 | 6e-05 |
Mask prototypes agree to 9e-06. A static-shape export of the same checkpoint agrees with this dynamic one to 2e-05 on square input.
Terms and attribution
This checkpoint is a derived research artifact. Use and redistribution must
comply with the terms of Manga109, MangaSeg, COO, the upstream checkpoints, and
Ultralytics. The Ultralytics exporter stamps AGPL-3.0 into the graph metadata.
Review those terms before commercial use or redistribution.
- Downloads last month
- 15