web-sdk-pp-detection 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,15 +4,15 @@
4
4
 
5
5
  基于 ONNX Runtime Web 的浏览器端 PP-Detection 目标检测 SDK,支持 PC、移动端与各类 H5 页面。
6
6
 
7
- 当前 SDK 版本为 **0.2.0**,完整变更见[发布说明](https://github.com/chenmohan123/web-sdk-PP-Detection/blob/main/docs/zh-CN/release-0.2.0.md)。
7
+ 当前 SDK 版本为 **0.3.1**,完整变更见[发布说明](https://github.com/chenmohan123/web-sdk-PP-Detection/blob/main/docs/zh-CN/release-0.3.1.md)。
8
8
 
9
9
  ## 安装
10
10
 
11
11
  ```bash
12
- pnpm add web-sdk-pp-detection@0.2.0
12
+ pnpm add web-sdk-pp-detection@0.3.1
13
13
  ```
14
14
 
15
- 也可以使用 `npm install web-sdk-pp-detection@0.2.0`。
15
+ 也可以使用 `npm install web-sdk-pp-detection@0.3.1`。
16
16
 
17
17
  ## 快速开始
18
18
 
@@ -82,15 +82,15 @@ const detector = await createPPDetection({
82
82
 
83
83
  A browser-first PP-Detection object detection SDK powered by ONNX Runtime Web for desktop, mobile, and H5 pages.
84
84
 
85
- The current SDK version is **0.2.0**. See the [release notes](https://github.com/chenmohan123/web-sdk-PP-Detection/blob/main/docs/en/release-0.2.0.md) for the complete changes.
85
+ The current SDK version is **0.3.1**. See the [release notes](https://github.com/chenmohan123/web-sdk-PP-Detection/blob/main/docs/en/release-0.3.1.md) for the complete changes.
86
86
 
87
87
  ### Installation
88
88
 
89
89
  ```bash
90
- pnpm add web-sdk-pp-detection@0.2.0
90
+ pnpm add web-sdk-pp-detection@0.3.1
91
91
  ```
92
92
 
93
- `npm install web-sdk-pp-detection@0.2.0` is also supported.
93
+ `npm install web-sdk-pp-detection@0.3.1` is also supported.
94
94
 
95
95
  ### Quick start
96
96
 
@@ -149,6 +149,10 @@ From 0.2.0, without an active detector, `ModelManager.getCacheEstimate({ id, ver
149
149
 
150
150
  WeChat official-account pages and other H5/WebView integrations are supported. Native Mini Program inference is not claimed; a native Mini Program should host the H5 experience in a WebView or use server-side inference.
151
151
 
152
+ ### PP-YOLOE 稳定模型(0.3.0 起)
153
+
154
+ 0.3.0 配套提供 PP-YOLOE+ S 640 FP32 `0.1.0 stable` 清单,模型从 ModelScope 或 Hugging Face 的固定 revision 下载,npm 包不包含权重。见[模型接入](https://github.com/chenmohan123/web-sdk-PP-Detection/blob/v0.3.0/examples/ppyoloe-candidate/README.md)。`allowExperimental` 默认关闭,仅运行 labs 候选时显式开启;blocked 仍被拒绝。Demo 默认 PicoDet,两个模型均默认 ModelScope。
155
+
152
156
  ### Documentation
153
157
 
154
158
  - [Chinese documentation](https://github.com/chenmohan123/web-sdk-PP-Detection#readme)
@@ -14007,34 +14007,58 @@ ${u}`, c = n.createShaderModule({ code: d, label: e.name });
14007
14007
  const rounded = value >> BICUBIC_PRECISION_BITS;
14008
14008
  return Math.max(0, Math.min(255, rounded));
14009
14009
  }
14010
- function bicubicChannel(raster, resizedWidth, resizedHeight, channel) {
14010
+ function writeBicubicChannels(raster, resizedWidth, resizedHeight, target) {
14011
14011
  const horizontal = createBicubicAxis(raster.width, resizedWidth);
14012
14012
  const vertical = createBicubicAxis(raster.height, resizedHeight);
14013
- const intermediate = new Uint8Array(raster.height * resizedWidth);
14013
+ const rowStride = resizedWidth * 3;
14014
+ const intermediate = new Uint8Array(raster.height * rowStride);
14014
14015
  for (let y = 0; y < raster.height; y += 1) {
14016
+ const sourceRow = y * raster.width * 4;
14017
+ const targetRow = y * rowStride;
14015
14018
  for (let x = 0; x < resizedWidth; x += 1) {
14016
14019
  const [start, count] = horizontal.bounds[x];
14017
14020
  const coefficients = horizontal.coefficients[x];
14018
- let sum = BICUBIC_ROUNDING;
14021
+ let red = BICUBIC_ROUNDING;
14022
+ let green = BICUBIC_ROUNDING;
14023
+ let blue = BICUBIC_ROUNDING;
14024
+ let source2 = sourceRow + start * 4;
14019
14025
  for (let index = 0; index < count; index += 1) {
14020
- sum += raster.rgba[(y * raster.width + start + index) * 4 + channel] * coefficients[index];
14026
+ const coefficient = coefficients[index];
14027
+ red += raster.rgba[source2] * coefficient;
14028
+ green += raster.rgba[source2 + 1] * coefficient;
14029
+ blue += raster.rgba[source2 + 2] * coefficient;
14030
+ source2 += 4;
14021
14031
  }
14022
- intermediate[y * resizedWidth + x] = clipBicubic(sum);
14032
+ const offset = targetRow + x * 3;
14033
+ intermediate[offset] = clipBicubic(red);
14034
+ intermediate[offset + 1] = clipBicubic(green);
14035
+ intermediate[offset + 2] = clipBicubic(blue);
14023
14036
  }
14024
14037
  }
14025
- const output = new Uint8Array(resizedWidth * resizedHeight);
14038
+ const plane = target.inputWidth * target.inputHeight;
14026
14039
  for (let y = 0; y < resizedHeight; y += 1) {
14027
14040
  const [start, count] = vertical.bounds[y];
14028
14041
  const coefficients = vertical.coefficients[y];
14042
+ const sourceRow = start * rowStride;
14043
+ const targetRow = (y + target.padTop) * target.inputWidth + target.padLeft;
14029
14044
  for (let x = 0; x < resizedWidth; x += 1) {
14030
- let sum = BICUBIC_ROUNDING;
14045
+ let red = BICUBIC_ROUNDING;
14046
+ let green = BICUBIC_ROUNDING;
14047
+ let blue = BICUBIC_ROUNDING;
14048
+ let source2 = sourceRow + x * 3;
14031
14049
  for (let index = 0; index < count; index += 1) {
14032
- sum += intermediate[(start + index) * resizedWidth + x] * coefficients[index];
14050
+ const coefficient = coefficients[index];
14051
+ red += intermediate[source2] * coefficient;
14052
+ green += intermediate[source2 + 1] * coefficient;
14053
+ blue += intermediate[source2 + 2] * coefficient;
14054
+ source2 += rowStride;
14033
14055
  }
14034
- output[y * resizedWidth + x] = clipBicubic(sum);
14056
+ const offset = targetRow + x;
14057
+ target.data[offset] = target.values[clipBicubic(red)];
14058
+ target.data[plane + offset] = target.values[256 + clipBicubic(green)];
14059
+ target.data[plane * 2 + offset] = target.values[512 + clipBicubic(blue)];
14035
14060
  }
14036
14061
  }
14037
- return output;
14038
14062
  }
14039
14063
  function preprocessImage(raster, preprocessing) {
14040
14064
  const inputWidth = preprocessing.size.width;
@@ -14061,18 +14085,35 @@ ${u}`, c = n.createShaderModule({ code: d, label: e.name });
14061
14085
  const mean = normalize ? preprocessing.mean ?? [0, 0, 0] : [0, 0, 0];
14062
14086
  const std = normalize ? preprocessing.std ?? [1, 1, 1] : [1, 1, 1];
14063
14087
  const interpolation2 = preprocessing.interpolation ?? "bilinear";
14088
+ const bicubicValues = doResize && interpolation2 === "bicubic" ? new Float32Array(256 * 3) : void 0;
14064
14089
  for (let channel = 0; channel < 3; channel += 1) {
14065
14090
  const padding = normalize && mean[channel] !== 0 ? -mean[channel] / std[channel] : 0;
14066
14091
  data.fill(padding, channel * plane, (channel + 1) * plane);
14067
- const bicubic = doResize && interpolation2 === "bicubic" ? bicubicChannel(raster, resizedWidth, resizedHeight, channel) : void 0;
14092
+ if (bicubicValues) {
14093
+ for (let pixel = 0; pixel < 256; pixel += 1) {
14094
+ const scaled = rescale ? pixel * preprocessing.rescaleFactor : pixel;
14095
+ bicubicValues[channel * 256 + pixel] = normalize ? (scaled - mean[channel]) / std[channel] : scaled;
14096
+ }
14097
+ continue;
14098
+ }
14068
14099
  for (let y = 0; y < resizedHeight; y += 1) {
14069
14100
  for (let x = 0; x < resizedWidth; x += 1) {
14070
- const pixel = bicubic ? bicubic[y * resizedWidth + x] : doResize ? bilinearChannel(raster, x, y, resizedWidth, resizedHeight, channel) : sampleChannel(raster, x, y, channel);
14101
+ const pixel = doResize ? bilinearChannel(raster, x, y, resizedWidth, resizedHeight, channel) : sampleChannel(raster, x, y, channel);
14071
14102
  const scaled = rescale ? pixel * preprocessing.rescaleFactor : pixel;
14072
14103
  data[channel * plane + (y + padTop) * inputWidth + x + padLeft] = normalize ? (scaled - mean[channel]) / std[channel] : scaled;
14073
14104
  }
14074
14105
  }
14075
14106
  }
14107
+ if (bicubicValues) {
14108
+ writeBicubicChannels(raster, resizedWidth, resizedHeight, {
14109
+ data,
14110
+ inputWidth,
14111
+ inputHeight,
14112
+ padLeft,
14113
+ padTop,
14114
+ values: bicubicValues
14115
+ });
14116
+ }
14076
14117
  return {
14077
14118
  data,
14078
14119
  dims: [1, 3, inputHeight, inputWidth],
@@ -15667,13 +15708,19 @@ ${u}`, c = n.createShaderModule({ code: d, label: e.name });
15667
15708
  if (executionMode === "worker" && !capabilities.worker) {
15668
15709
  fail("CAPABILITY_UNSUPPORTED", "\u8BF7\u6C42\u7684 worker \u4E0D\u53EF\u7528", { executionMode });
15669
15710
  }
15670
- const variant3 = manifest.variants?.find(
15671
- (candidate) => candidate.precision === requestedPrecision && candidate.status !== "labs" && candidate.status !== "blocked"
15672
- );
15711
+ const matchingVariants = manifest.variants?.filter(
15712
+ (candidate) => candidate.precision === requestedPrecision && candidate.status !== "blocked"
15713
+ ) ?? [];
15714
+ const variant3 = matchingVariants.find((candidate) => candidate.status !== "labs") ?? (options.allowExperimental === true ? matchingVariants.find((candidate) => candidate.status === "labs") : void 0);
15673
15715
  if (!variant3) {
15674
- fail("MODEL_INCOMPATIBLE", `manifest \u6CA1\u6709\u53EF\u7528\u7684 ${requestedPrecision} \u7A33\u5B9A\u53D8\u4F53`, {
15675
- requestedPrecision
15676
- });
15716
+ fail(
15717
+ "MODEL_INCOMPATIBLE",
15718
+ options.allowExperimental === true ? `manifest \u6CA1\u6709\u53EF\u7528\u7684 ${requestedPrecision} \u53D8\u4F53` : `manifest \u6CA1\u6709\u53EF\u7528\u7684 ${requestedPrecision} \u7A33\u5B9A\u53D8\u4F53`,
15719
+ {
15720
+ requestedPrecision,
15721
+ allowExperimental: options.allowExperimental === true
15722
+ }
15723
+ );
15677
15724
  }
15678
15725
  const candidates = candidatesForBackend(requestedBackend, capabilities).filter(
15679
15726
  (backend) => variant3.backends.includes(backend)
@@ -15849,7 +15896,7 @@ ${u}`, c = n.createShaderModule({ code: d, label: e.name });
15849
15896
  };
15850
15897
 
15851
15898
  // src/index.ts
15852
- var CURRENT_SDK_VERSION = "0.2.0";
15899
+ var CURRENT_SDK_VERSION = "0.3.1";
15853
15900
  function probePPDetectionCapabilities(options = {}) {
15854
15901
  return probeCapabilities(options);
15855
15902
  }
@@ -15964,6 +16011,7 @@ ${u}`, c = n.createShaderModule({ code: d, label: e.name });
15964
16011
  options.onProgress?.({ phase: "manifest", status: "complete" });
15965
16012
  const plan = selectExecutionPlan(
15966
16013
  {
16014
+ allowExperimental: options.allowExperimental,
15967
16015
  backend: options.backend,
15968
16016
  precision: options.precision === "auto" ? void 0 : options.precision,
15969
16017
  executionMode: options.executionMode,