OpenCV 图像识别 - 更新日志
2.6.3(2026-09-24)
-
注意(App-Android / uni-app x):UTS 编译到 Kotlin 后端时不生成可选参数的默认值,调用可选参数的 API 需显式传全, 例如
findContours(id, 'external', 'simple')、warpAffine(id, m, 0, 0)、distanceTransform(id, 0)、boxFilter(id, 9, 1); 省略会报No value passed for parameter 'xxx'。传入的值与各端实现里??的默认值相同,故结果与省略时一致。 iOS / web / 小程序 / 鸿蒙后端不受此限制。 -
App 端(iOS / Android)路径兼容:
loadImage现在能直接接受 uni-app x 的虚拟路径与包内资源路径 ——unifile://...(如uni.env.USER_DATA_PATH)、/static/...、static/...、_www/...会先经UTSiOS.convert2AbsFullPath/UTSAndroid.convert2AbsFullPath转成真实文件路径;http(s)、data:、file://与普通绝对路径行为不变(原样透传)。 这样 App 端「内置示例图」这类包内静态资源也能直接加载,不必再依赖相册。 -
说明:
unifile://是运行时虚拟 scheme(实测uni.env.USER_DATA_PATH=unifile://usr/), 原生 OpenCV 无法直接读取,故在插件侧统一转换。 -
版本依赖:App 路径兼容在 Android 侧依赖
UTSAndroid.convert2AbsFullPath(uni-app x 3.90 起 / uni-app 的 UTS 插件内可用), iOS 侧依赖UTSiOS.convert2AbsFullPath(uni-app x 4.11 起;本插件整体要求 HBuilderX ≥ 4.61,已覆盖)。 iOS 端转换先于 Android 侧落地(两次提交),对本版使用者无差别。
2.6.2(2026-09-23)
鸿蒙端交付改造:源码授权版零配置;插件包鸿蒙体积 22MB → 9MB
-
源码授权版鸿蒙端:零配置。插件包不再散放裸
.so,改为随包提供只含原生库的载体 har (utssdk/app-harmony/libs/opencv-image-libs.har,9MB,内含 arm64-v8a + x86_64 两套libopencv_bridge.so/libc++_shared.so),并在插件utssdk/app-harmony/config.json中声明该依赖 —— HBuilderX 生成鸿蒙工程时会自动把 har 拷入模块目录、按config.json生成模块oh-package.json5,ohpm再解包其中libs/**合并进应用。事项 之前(≤2.6.1) 现在(2.6.2) 买家要做什么 手动把 utssdk/app-harmony/libs/<ABI>/*.so同步到工程harmony-configs/entry/libs/<ABI>/什么都不用做(仅需工程自带 EntryAbility) 插件包鸿蒙部分 裸 .so22MB载体 har 9MB 源码改动是否仍生效 生效 生效(源码流程编译源码,har 只提供原生库) -
⚠️ 普通授权版(加密包)的鸿蒙端不支持 —— 受 DCloud 官方限制:官方规则为 "发行平台为 web / 小程序 / 鸿蒙时,UTS 加密插件需云端编译,目前仅支持 uni-app x 项目,不支持 uni-app 项目"; HBuilderX 中该分支由
isX(UNI_APP_X === "true")守卫,uni-app(Vue2/Vue3) 工程不触发。 需要鸿蒙请选择源码授权版。 -
升级提示:
- 若你此前按旧文档把
.so复制到了工程harmony-configs/entry/libs/,可以删除(不再需要,也不影响构建)。 - 鸿蒙端 API、数值与行为完全不变(OpenCV 4.9.0 内核未动;真机全序列与 2.6.1 基线一致)。
- 若你此前按旧文档把
-
引擎仍为 OpenCV 4.9.0,API 数量不变(77)。
2.6.1(2026-09-22)
新增:H5 / 微信小程序 纯 JS 入口(普通授权版五端可用性恢复)
DCloud 加密 UTS 插件的解密只发生在 App 云打包;uni-app(Vue2/Vue3) 工程的 H5 / 微信小程序
端在本地编译时无法解密加密 .uts(官方规则:加密插件 web/小程序/鸿蒙需云端编译且仅支持
uni-app x)。本版为两个平台提供随包明文 JS 入口,API 与 UTS 完全同名同参、返回值一致:
| 入口 | 平台 | 说明 |
|---|---|---|
js_sdk/index.js |
H5(浏览器) | opencv-wasm 引擎 + web-helper I/O,77 API 同签名 |
js_sdk/mp-index.js |
微信小程序 | 裁剪 wasm 引擎 + 画布桥;宿主需先 bindProcessingCanvas(canvas)(与 UTS 版要求一致) |
- 导入方式见 README「授权与交付」的条件编译示例;App 端仍走 UTS 入口(云打包),导入路径不变。
js_sdk明文入口的 API 签名由utssdk/web/index.uts真源机械生成(生成脚本 + 签名护栏 + 双引擎运行时等价验证,同一输入两引擎输出逐字节一致),后续版本随 UTS 同步再生成。- 对既有源码授权版用户:无任何行为变化,无需迁移。
- 引擎仍为 OpenCV 4.9.0,API 数量不变(77)。
2.6.0(2026-09-19)
新增:5 个几何 / 体验 API —— 五端可用(API 总数 72 → 77)
| API | 说明 |
|---|---|
imageSize(id) |
图像尺寸,返回 { width, height };句柄无效 width=-1 |
getRoi(id, x, y, w, h) |
ROI 裁剪(平移仿射实现,像素精确);越界 / 非法尺寸返回 -1,结果需 releaseImage |
rotate(id, angleDeg, scale?) |
任意角度旋转:angleDeg 正值=逆时针(度),与 flipRotate 方向一致;scale 缩放内容 |
matchTemplateMultiScale(id, templateId, topN?, scales?) |
多尺度模板匹配:模板按各尺度缩放后与原尺寸源图匹配,跨尺度 NMS 去重 |
releaseAll() |
释放池内全部句柄,返回释放数量 |
行为契约
rotate:90 的倍数且scale=1时走像素精确路径(flipRotate)并互换宽高;其它角度为同尺寸仿射(四角黑边),宽高不变。matchTemplateMultiScale:返回 JSON[{ x, y, width, height, score, scale }](score 降序;scale>1表示实例比模板大;box 为模板尺寸在源图坐标系);默认scales=[0.6,0.8,1.0,1.5]、topN=3;每尺度一次全图匹配,大图建议先resize降采样。releaseAll释放后原句柄全部失效,句柄计数器不清零(与loadImage后的序号连续行为一致)。getRoi/rotate返回新句柄,同样需要releaseImage;不修改源图(非破坏式)。
跨端差异
releaseAll:H5 / 微信小程序为 OcvCore 实现,导入即可用;App 三端(Android / iOS / 鸿蒙)为原生实现,需随 2.6.0 基座产物运行——自编基座的项目需重新打基座,否则调用报未找到。rotate非 90 倍数角度的插值结果与原生各端亚像素插值一致;跨端数值与模板匹配家族基线一致(详见验收)。
五端验收(2026-09-18,真机 + 模拟器全量复核)
- 照片基线(1440×2560)五端逐项复核通过:红色 130196 / 轮廓 4967(鸿蒙族 4955)/ 模板 0.519(原生族)· 0.492(wasm 族)· 0.863(鸿蒙族)/ 霍夫直线 2151(真机 arm64)· 2147(模拟器与 wasm 族)/ 霍夫圆 30@(973,1470) r=198 全端一致。
- 压力:Android 真机连打 40+31 次、x86_64 模拟器 31+32 次、鸿蒙真机 32+30 次、H5 浏览器 15 次、mp 真机 5+19 次、iOS 真机 71 次 + 模拟器 47 次(1016–1334ms 真机 / 505–620ms 模拟器)——全部零漂移零崩溃。
- 工具链分族提醒:模板分数 / 霍夫直线在原生 arm64、x86_64 模拟器、wasm、鸿蒙四族间存在既定基线差异(见 README「跨端差异」),回归时按族对照,不跨族比较。
升级注意
- App 三端(Android / iOS / 鸿蒙)升级后需重新以 2.6.0 基座运行(自编基座需重新打包基座);H5 / 微信小程序无额外动作。
- 引擎仍为 OpenCV 4.9.0,既有 API 行为与数值无变化。
2.5.0(2026-09-10)
新增:二维码(QR)4 个 API —— 五端可用
| API | 说明 |
|---|---|
qrEncode(text) |
文本生成二维码,返回 8UC1 二值图句柄(需 releaseImage) |
qrDetect(id) |
检测二维码,返回 { ok, points: [{x,y}×4] } 四角点 |
qrDecode(id) |
解码二维码,返回 { ok, text } |
qrDetectAndDecode(id) |
一步检测 + 解码,返回 { ok, points, text } |
- 解码要求被解图内二维码模块 ≥ 10 像素(模块过小时先用
resize放大再解码)。 - 类型定义:
OcvQrPoint/OcvQrDetectResult/OcvQrDecodeResult。
引擎升级:OpenCV 4.8 → 4.9.0
- 模块范围:core / imgproc / features2d / flann / calib3d / objdetect(图片解码按平台选用系统 codec)。
- 既有 API 行为与数值不变:合成图基线(OTSU 141 / 三角法 12 / 霍夫直线 131 / 霍夫圆 1 / Shi-Tomasi 13)与 4.8 完全一致,68 项 API 无回归。
- 二维码解码能力随 4.9 落地:4.8 时代的解码器存在上游缺陷(检测正常但部分二维码解码为空),因此 2.4.0 未交付解码能力,改为随内核升版一并提供。
五端验收基线(同一张 1440x2560 照片)
| 指标 | mp | H5 | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|
| 内核 | 4.9.0 | 4.9.0 | 4.9.0 | 4.9.0 | 4.9.0 |
| 红色像素 | 130196 | 130196 | 130196 | 130196 | 130196 |
| OTSU / 三角 | 155 / 78 | 155 / 78 | 155 / 78 | 155 / 78 | 155 / 78 |
| 霍夫直线 | 2147 | 2147 | 2151 | 2147 | 2151 |
| 模板最佳分 | 0.492@[583,2171] | 0.492@[583,2171] | 0.519@[582,2171] | 0.519 | 0.519 |
| 霍夫圆 | 30 | 30 | 30 | 30 | 30 |
| 轮廓 / 层级树 | 4967 / 顶1深1 | 4967 / 顶1深1 | 4967 / 顶1深1 | 4967 / 顶1深1 | 4955 / 顶1深1 |
| QR 四按钮 | 全通 | 全通 | 全通 | 全通 | 全通 |
| QR 角点 | [[28,30],[449,28],…] |
同 mp | [[28,30],[450,29],…] |
同 mp | 同 Android |
- 数值分两族:wasm 端(H5 / 小程序) 与 原生端(App / 鸿蒙),两者只在浮点敏感指标上差最后一档(霍夫直线 2147 vs 2151、模板分 0.492 vs 0.519、示例图模板分 0.813 vs 0.873)。成因是向量化内核与标量内核的浮点归约顺序不同,不影响阈值判定与业务结论。
- 示例图 400x300 基线(mp 与 H5 逐项同值):红色 9477、轮廓 23、模板 0.813@[55,75]、霍夫直线 412、霍夫圆 0、凸包 119301、ORB 297/295、OTSU 150·253。
修复
- H5:在 HBuilderX 内置浏览器(QtWebEngine 5.12 / Chromium 69)初始化失败(报
wasm function signature contains illegal type),现代浏览器正常。已修复,并复核内置浏览器与外部浏览器数值一致。 - 鸿蒙:霍夫圆检测偶发返回 0 个(同图重跑概率性发生)。已修复,现与其它端一致多线程执行且结果稳定。
- iOS:二维码接口偶发 JSON 解析失败(报「未能读取数据,因为它的格式不正确」)。已修复。
- 鸿蒙 / demo:二维码生成后的结果图预览异常(鸿蒙端横向重复 4 份并纵向压扁;demo 端被压成 203x360 非等比)。二维码数据本身正常,预览已与其它端一致。
2.4.0(2026-09-09)
图像增强 A 档扩展(imgproc,五端):
applyColorMap(id, colormap):伪彩映射(COLORMAP_AUTUMN/BONE/JET/WINTER/.../TURBO/DEEPGREEN 共 22 种, 参数用字符串名'jet'/'turbo'等;RGBA(4ch) 输入自动转灰度,输出 3ch 彩色句柄需 releaseImage)cornerHarris(id, blockSize?, ksize?, k?):Harris 角点响应图(32F 响应归一化 0-255 转 8U 单通道 句柄返回,可 toBase64 展示;非灰度自动转灰,blockSize 可为偶数、ksize 自动奇数化,默认 blockSize=2、ksize=3、k=0.04)goodFeaturesToTrack(id, maxCorners, qualityLevel?, minDistance?):Shi-Tomasi 角点检测, 返回{ corners: [{x,y}], count }(默认 qualityLevel=0.01、minDistance=10)- 均为 imgproc 模块现成能力,mp/H5 wasm 不新增模块依赖,App 三端薄桥直调原生
平台实现:
- mp-weixin:
shim_full.cpp新增 3 个 C ABI +opencv-facade.js/opencv-core.js外观层 (wasm 2.37MB → 2.38MB,体积基本不变;白盒数值验证:40×40 亮块图检出 4 个角点坐标精确命中) - H5 / Android / iOS / 鸿蒙:与 mp 同签名(跨端数值一致),实现随各端薄桥
- 类型:
interface.uts新增 ColorMapType / OcvCorner / OcvGoodFeaturesResult
二维码(QRCodeDetector)延后说明:原计划 2.4.0 纳入 QR 检测解码,但 OpenCV 4.8.0 旧版 QRCodeDetector(依赖第三方 QUIRC)解码存在上游通用缺陷——detect 正常但部分 二维码解码为空(opencv/opencv#23249 / #24318,维护者 asmorkalov 亲测复现, Android/桌面/wasm 一致,非插件移植问题)。官方已在 4.9.0+ 提供自研解码器 (PR #24299 "In-house QR codes decoding", 构建时关闭 QUIRC 即生效),故 QR 延后至随 OpenCV 升版(2.5.0)一并引入, 避免在 4.8.0 上交付带缺陷的解码能力。
修复(2.3.0 遗留:mp wasm 分发位置错误):2.3.0 将 wasm 放在插件 js_sdk/,但 uni 编译
小程序时只编译 js_sdk 内的 JS 模块,.wasm 二进制不会拷入产物(实测 dist 内无该文件),
运行时 WXWebAssembly.instantiate 与 fs 回退均报 not found。2.4.0 修正:
wasm 唯一来源移至插件 uni_modules/axen-opencv-image/static/opencv_mp.wasm(随 uni 资产管线
打包进小程序包,插件自包含),loader 改为多候选路径探测(插件 static 源路径 → 合入根
/static/ → 旧 js_sdk 兜底),兼容不同 uni 版本的产物路径差异。
修复(2.2.0 遗留:findContoursHierarchy 原生三端层级错乱):OpenCV 的 hierarchy 为
1×N CV_32SC4(源码 create(1, total, CV_32SC4)),ptr<int> 线性化后每轮廓占 4 个 int;
Android/iOS/鸿蒙桥接误用 conn = hierarchy.cols / n(=1),把 Vec4i 错读成滑动窗口,
导致 parent/child/next/prev 全错(mp/H5 的 JS 端 i*4 步长一直正确)。单轮廓图不暴露,
大图(15 轮廓嵌套)下 iOS 输出 顶层=5/深度=2 而 mp 正确输出 顶层=1/深度=1。修复:
conn = (cols × channels) / n(对 CV_32SC4 与假想的 CV_32SC1-4N-cols 两种布局均稳健)。
mp 与 iOS 从错读值反推出的真实层级完全自洽,交叉验证成立。随修复同步重编预编译产物:
iOS libOpenCVBridge.a(fat x86_64+arm64)、鸿蒙 libopencv_bridge.so(arm64-v8a + x86_64,
strip 后 5.3M/8.6M)、Android opencv-4.8.0.aar(4 ABI,32.6M,含 A 档 3 个新 JNI 符号,
nm 已验证)。
优化(mp:wasm brotli 压缩分发):微信小程序 WXWebAssembly.instantiate 自基础库 2.14.0
起原生支持 .wasm.br 后缀(brotli 自动解压,官方推荐方案)。本次将 mp wasm 从原始 .wasm
(2.38MB)改为 brotli q11 压缩的 .wasm.br(0.56MB,原始的 23.3%)作为唯一分发格式。
预览 4MB 限制下节省 1.83MB(wasm 从占预算 60% 降至 14%);正式上传 gzip 计费下亦从 0.72MB
(gzip of raw)降至约 0.56MB(gzip of br)。loader 探针改为 .wasm.br 优先 → .wasm 兜底
(WXWebAssembly 通道),fs 回退仅探 .wasm(标准 WebAssembly 无法解压 brotli)。
Node 冒烟:.br 解压 → 字节注入 → 全函数(含 A 档)正常。
修复(鸿蒙:HoughCircles 运行间非确定):同一输入(同文件、同操作序列,霍夫直线两轮恒 2151
证明输入一致)下 HoughCircles 两轮输出 0/30 圆跳变;mp 端 wasm 为 USE_PTHREADS=0 单线程,
同输入恒定 30。OpenCV 4.8 的 HoughCircles 三个阶段均为 parallel_for_ 分条并行,鸿蒙端
setNumThreads(2) 下的分条行为在运行间不稳定。修复:鸿蒙 HoughCircles 固定单线程执行
(RAII guard,异常安全,结束恢复原线程数),对齐 mp 的确定性路径。耗时约 2.2s→4.4s(1440x2560),
仍低于 6s 主线程阻塞阈值;>2880px 走既有降采样兜底。
H5 A 档绑定:opencv.js(embind 裁剪构建)此前无 applyColorMap/cornerHarris/goodFeaturesToTrack。
本次在 core_bindings.cpp 手写三个包装器(契约对齐 OcvCore/mp facade:goodFeaturesToTrack
无 mask 参数、corners 为 JS 数组 push {x,y}),经 embindgen 重新生成 bindings.cpp 并重编
opencv-h5-official 构建树,组装链(DATACOUNT 手术 + binaryen MVP 降级 + ES2019)产出新
js_sdk/opencv.js。node 冒烟 70/70 全绿(含 A 档三项)。
修复(H5 组装链复用残留旧 wasm):组装脚本 binaryenToMvp 从固定路径 /tmp/ocv-b0.wasm
读输入但从未写入,重装时复用 2.2.0 时代残留旧 wasm → 新 glue(含 A 档 embind 注册)配旧 wasm
(无对应实现)→ 浏览器初始化 promise resolve undefined → H5 选图无响应。修复:DATACOUNT
手术后先落盘再进 binaryen;同修 --print 步骤缺失 EN 特性开关(trunc_sat 解析失败)。
新产物 4.37MB / 内嵌 wasm 3.14MB;浏览器环境模拟 + 组装产物全量冒烟 70/70 双验证。
2.3.0(2026-09-06)
微信小程序(mp-weixin)支持 —— 无 embind 架构:
- 背景:微信小程序逻辑层禁 eval/new Function(微信注入假桩),opencv.js 的 embind
绑定层(craftInvokerFunction 依赖 new Function)在逻辑层必然崩溃;逻辑层亦无标准
WebAssembly(仅
WXWebAssembly),且无performance全局。 - 方案:纯 C ABI wasm + 纯 JS 外观层替代 embind,数值与 Android/iOS/H5 同源
(同一份 OpenCV 4.8.0 C++ 内核):
native/mp-weixin/shim_full.cpp:Mat 句柄 + 全部算法导出(无 embind、0 处 new Function)js_sdk/opencv-facade.js:embind 兼容 cv 外观(Mat/MatVector/值对象/50+ 函数/常量/typed 数据视图)- 加载:
WXWebAssembly.instantiate('/static/opencv_mp.wasm')(嵌套 imports), glue 用 web,worker 环境 ESM(免modulepolyfill)、中和import.meta.url、注入performance垫片 - I/O:canvas2d 像素桥(getImageData/putImageData→toTempFilePath),包内路径归一化 + 直载兜底
- 体积:小程序增量 ~2.4MB(wasm 2.3MB + glue/facade ~0.1MB),远低于预览/发布限制
- 验证:微信开发者工具 3.16.2 模拟器与真机双绿,65 API 全量;数值与各端基线一致 (示例图 test.png:红色 9477 / 连通域 120000 / 直方图峰值 255 / OTSU 150;相册大图: 130196 / OTSU 155 / 霍夫圆 30 / 凸包 3682401 等)
- 构建复现:
native/mp-weixin/build-mp-nobind.sh(emcc 重链)+scripts/package-mp-wasm.cjs(打包) - 已知小差异(不影响语义):canvas 解码的像素级偏差 → 示例图模板匹配分数 0.794(H5/Node 1.0,
命中位置一致 [55,75]);霍夫直线大图 2147(Android 2151,首条一致)
更新日志
2.2.0(2026-09-05)
轮廓层级树(imgproc):
findContoursHierarchy(id, retrMode?, approxMode?):RETR_TREE 层级轮廓分析,返回{ contours, hierarchy, maxDepth }——contours 与 findContours 同字段(含index), hierarchy 每条为{ index, parent, child, next, prev, depth }(次序按 OpenCV 惯例 next/prev/child/parent,-1 表示无;depth 顶层=0 顺序递推),maxDepth 为树最大深度- retrMode 默认
tree(也支持 external/list/ccomp),approxMode 默认simple - 失败/空图返回
{"contours":[],"hierarchy":[],"maxDepth":0} - 典型用途:区分容器轮廓与孔洞(父→子=外边界→内边界)、按 depth 分层涂色、抠出内部组件
平台实现:
- Android:
android-bridge.cpp新增 findContoursHierarchy JNI(薄桥重编 4 ABI,aar 12.45M) - iOS:
OpenCVBridge.mm/.h新增方法(自编库重编) - 鸿蒙:
napi_bridge.cpp新增 NAPI +OpenCVBridge.ets/index.d.ts/index.uts - H5:
opencv-core.js新增方法 +web/index.uts导出 - 类型:
interface.uts新增 OcvHierarchyEntry/OcvHierarchyResult +opencv-core.d.ts - 契约:各端 hierarchy 读取一致(1×N CV_32SC1 每元素 4 值),数值四端对齐
H5 体积与兼容(并入 2.2.0):
opencv.js9.99M → 3.96M(-60%):模块级裁剪(core/imgproc/features2d)+ 函数级白名单- 链接级
--gc-sections三层精简,65 API 全量保留
- 链接级
- 兼容 QtWebEngine 5.12 / Chromium 69(HBuilderX 内置浏览器):wasm 降级至纯 MVP ——
DATACOUNT section 移除、
trunc_sat→trunc(WAT 文本层替换)、sign-ext/bulk/SIMD 降级、 blocktype 标准 s33 编码、-s WASM_BIGINT=0(解决导出函数含 i64 在 V8 6.9 的signature contains illegal type) - 数值与全量版逐位一致(130196 / 4946 / OTSU 155 / 霍夫 2147·30 / ORB 500(大图)与 150(小图)/
compareHist=1 / 3686377 等),65 API 全绿;
scripts/assemble-h5-opencv.cjs可复现组装链,docs/H5-TRIM.md记录完整排障
2.1.1(2026-09-03)
- 清除 iOS
--install残留的libOpenCVBridge.a.bak(46.35M 旧库备份被打进插件 zip → 50M) - 插件 zip 实测 37,278,259(37.2M),体积战役成果保持(-71%)
- 功能面与 2.1.0 完全一致(无代码变更,仅发布产物修正)
2.1.0(2026-09-03)
直方图族(imgproc):
calcHist(id, bins?):灰度直方图(非灰度自动转灰,bins 默认 256)。返回直方图句柄(1×N 8U,归一化 0-255,可 toBase64 展示)+bins数值数组(峰值=最亮 bin 计数归一到 255)。失败{"id":-1,"bins":[]}calcBackProject(id, histId):以直方图句柄为模型的灰度级反投影(单通道灰度模型,像素值→该灰度的直方图强度),返回 8U 单通道反投影图句柄。hist 尺寸<2 返回{"id":-1}。非灰度自动转灰compareHist(h1, h2, method?):直方图相似度。method:correlation(默认,-1~1 越大越相似)/chisqr(越小越相似)/intersection(越大越相似)/bhattacharyya(0~1 越小越相似)。长度不符/无效返回{"value":-1}
连通域(imgproc):
connectedComponentsWithStats(id):连通域统计。返回{count, labelId, components:[{x,y,width,height,area,centerX,centerY}]};count 为非背景连通域数,components 按面积降序(跳过背景),labelId 为 labels 归一化转 8U 的可视化句柄(可 toBase64)。非灰度自动转灰。输入空/失败{"count":0,"labelId":-1,"components":[]}connectedComponents(id):仅返回 count(内部同 WithStats 实现,统一返回完整结构)
跨端契约:四个平台返回结构完全一致(iOS/Android/鸿蒙 JSON 字符串,H5 对象);直方图/反投影/连通域的句柄均为新句柄,用完需 releaseImage。OpenCV wasm 官方自带 calcHist/calcBackProject/compareHist/connectedComponents(WithStats) 符号(H5 预检通过,无需自编 wasm)。
平台实现:
- Android:
android-bridge.cpp新增 5 个 JNI 函数(薄桥重编 4 ABI,aar 12.44M) - iOS:
OpenCVBridge.mm/.h新增 5 个方法(自编库重编 46.5M) - 鸿蒙:
napi_bridge.cpp新增 5 个 NAPI 函数 +OpenCVBridge.ets/index.d.ts/index.uts(重编双 ABI,strip 同 2.0.1) - H5:
opencv-core.js新增 5 个方法 +web/index.uts导出 - 类型:
interface.uts新增 5 个返回类型(OcvHistResult/OcvBackProjectResult/OcvCompareResult/OcvComponent/OcvConnectedComponentsResult)+opencv-core.d.ts
2.0.1(2026-09-03)
Android 薄桥重构 + 四端体积优化,发布包 130M → 37M(-71%)
Android 薄桥(架构重构):
- 放弃 OpenCV Java wrapper(classes.jar + 全量 1124 个 JNI 入口 + converters 层),改为自写 C++ 薄桥
libopencv_bridge.so(native/android/android-bridge.cpp):59 个 API 全部 C++ 直实现,像素常驻 native 池(BGR 8UC3,cv::imread路径与历史基线一致,四端数值逐位对齐) OpenCVNative.kt重写为 external 薄层(公开签名不变,Application.kt调用面零改动),不再依赖org.opencv.*- aar:41.97M → 12.42M(-70%);arm64 薄桥 10.0M / v7a 5.6M / x86 8.3M / x86_64 8.3M(对比官方全模块 arm64 21M+ 减半)
- 移除了全部冗余
libc++_shared.so(薄桥-static-libstdc++自包含) - 已通过 Android arm64 真机 + 模拟器(emulator arm64)全量回归:59 API 全通,数值与 iOS/鸿蒙/H5 完全一致
修复的三连雷(JNI 加载层):
- 链接
--strip-all误删.dynsym动态导出 → 改llvm-strip --strip-unneeded(保留 JNI 导出) - JNI 函数缺
extern "C"被 C++ mangling(_Z60Java_...)→ ART 报No implementation found→ 已包裹 init/releaseImage漏改 Kotlin external 名init0/releaseImage0后缀 → 已对齐
四端体积优化:
- iOS:
libOpenCVBridge.a从官方全模块 192M 裁剪到 46.3M(7 模块 + 去 bitcode + 补 TIFF/JPEG2000/WEBP codec),zip 68M → 15.5M - 鸿蒙:
libopencv_bridge.sostrip(删 .symtab,代码字节不变),6.9M+10.4M → 5.2M+8.4M - Android:aar 41.97M → 12.42M;四端构建脚本与产物同步:
native/ios/build-trim-bridge.sh(iOS 自编裁剪 framework + 桥接合并)native/android/build-bridge.sh+android-bridge.cpp(Android 薄桥一键编译 4 ABI)
- 16KB 页大小对齐确认:64 位 ABI(arm64/x86_64)
p_align=0x4000满足 Google Play 要求 - 发布包实测:130M → 37.2M(-71%),四端功能面与官方一致
2.0.0(2026-09-03)
新增 15 个图像处理 API(四端统一:颜色空间 6 + 增强/像素 9 合并发版),版本 1.3.0(44 API)→ 2.0.0(59 API)
颜色空间扩展:
cvtLab/cvtXyz/cvtYCrCb:颜色空间转换(H5/鸿蒙 RGBA 池先转 BGR 再转,输出 3ch 数值通道图;非 3/4ch 输入返回 -1)grayToBgr:灰度(1ch)扩为 3 通道(便于灰度图叠加彩色标注)splitChannels:按内存物理序拆前 3 通道为三个单通道句柄(4ch→R,G,B;3ch→序内通道;对 LAB/HSV 产物拆分即得 L,a,b / H,S,V);<3ch 输入返回全 -1mergeChannels:三个单通道句柄按序合成 3ch 新句柄(与 splitChannels 同序)
增强与像素运算:
clahe:CLAHE 自适应直方图均衡(非灰度自动转灰,默认 clipLimit=2.0、tileSize=8)addWeighted:加权融合 dst=α·a+β·b+γ(尺寸/通道不一致返回 -1)convertScaleAbs:dst=|α·src+β| 转 8U(默认 α=1 β=0)bitwiseAnd/Or/Xor/Not:双图/单图位运算(双图尺寸/通道不一致返回 -1)boxFilter:均值模糊(ksize 自动奇数化,默认 normalize=true)distanceTransform:DIST_L2+mask3 → 归一化 0-255 转 8U 返回(可选阈值截断;避免 32F 无法 PNG 编码的跨端坑)
注意:splitChannels/mergeChannels 按内存物理序(不做 RGB/BGR 语义重排);对 cvtLab/cvtHsv 等转换产物拆分时四端通道序一致(L,a,b 等),对原图拆分则 Android/iOS(BGR) 与 H5/鸿蒙(RGBA) 序不同,跨端场景请对转换产物使用。
1.3.0(2026-09-02)
新增 10 个图像处理 API(四端统一,句柄模型不变,失败返回 -1 / 空 JSON)+ findContours 增强:
- 轮廓进阶:
convexHull(凸包,返回扁平点集 + 面积)、approxPolyDP(多边形逼近,epsilonRatio 默认 0.02)、minEnclosingCircle(最小外接圆)、minAreaRect(旋转矩形,angle -90~0)——均基于内部 findContours 取第 index 个轮廓,越界返回空结构 - 几何变换:
getAffineTransform/warpAffine(3 点仿射)、getPerspectiveTransform/warpPerspective(4 点透视,可指定输出尺寸)、pyrUp/pyrDown(图像金字塔上/下采样) - findContours 增强(向后兼容):新增可选参数
retrMode(external/list/ccomp/tree)与approxMode(simple/none);每项新增perimeter(周长)。旧调用(无参数)输出完全兼容。注:完整点集不随 findContours 返回(数千轮廓会使 JSON 达数十 MB 导致 parse 失败),请用convexHull/approxPolyDP获取点集
矩阵类参数统一用 number[] 传递(仿照 filter2D);变换矩阵生成 API 返回 JSON 字符串(跨端数组返回值桥接不可靠)。所有几何变换支持自定义输出尺寸(默认原图尺寸),INTER_LINEAR + BORDER_CONSTANT。
1.2.0(2026-09-01)
1.2.0(2026-08-28)
1.1.0(2026-08-28)
新增 8 个图像处理 API(四端统一,句柄模型不变,失败返回 -1):
- 形态学:
morphErode(腐蚀)/morphDilate(膨胀)/morphologyEx(开、闭、梯度、顶帽、黑帽) - 滤波与阈值:
adaptiveThreshold(自适应二值化,光照不均场景)、medianBlur(中值去椒盐噪声)、bilateralFilter(双边保边平滑) - 增强:
equalizeHist(直方图均衡化) - 几何:
flipRotate(水平/垂直翻转,逆时针旋转 90/180/270)
全部支持非灰度输入自动转灰度(bilateralFilter 除外,其按原色彩空间处理);ksize 自动修正为奇数。
1.0.0(2026-08-27)
首个公开版本。
核心能力(15 个 API,四端统一)
- 图像基础处理:
loadImage/releaseImage/resize/cvtGray/cvtHsv/threshold/gaussianBlur/drawRect/toBase64 - 颜色检测:
detectColorRange(HSV 范围过滤,返回命中像素数/占比/外接矩形) - 边缘检测:
canny - 轮廓与形状识别:
findContours(面积/外接矩形/顶点数/形状分类 circle·rectangle·triangle·quad·other) - 模板匹配:
matchTemplate(TM_CCOEFF_NORMED + NMS,Top N 位置与分数) - 特征点匹配:
orbMatch(ORB + BFMatcher(HAMMING) + 0.75 比率测试)
平台支持
| 平台 | 引擎 | 说明 |
|---|---|---|
| App-Android | OpenCV 4.8.0 | 官方 classes.jar + 原生 so 重打包 aar 内置(4 ABI),兼容 Android 14+(bionic __sfp_handle_exceptions 移除问题已规避) |
| App-iOS | OpenCV 4.8.0 | pod OpenCV 4.8.0 + 预编译 ObjC++ 桥接库(内置模拟器版,真机需 device 模式重编,见 docs/IOS.md) |
| 鸿蒙 HarmonyOS | OpenCV 4.8.0 | OHOS 交叉编译 libopencv_bridge.so(NAPI 桥,句柄制零拷贝架构),arm64-v8a + x86_64 双 ABI |
| H5 (web) | opencv-wasm 4.3.0 | wasm 内联 + 异步编译改造 |
工程质量
- 四端算法完全一致(同一 OpenCV 4.8.0),跨端契约统一(错误码/空值结构/参数语义)
- 句柄制架构:像素常驻 native/wasm 内存,跨语言调用零像素拷贝(Android/iOS/鸿蒙/H5 同构)
- 健壮性:非法输入全兜底(彩色自动转灰/尺寸校验/颜色回退)、异常不穿透边界、无已知内存泄漏
- 经 7 轮代码审查,累计修复 35+ 项(功能/内存/跨端一致性/边界条件)
- 所有图像处理均在本地完成,不上传任何数据、不新增权限