ms-vite-plugin 1.4.49 → 1.4.51

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.
Files changed (42) hide show
  1. package/dist/build.js +1 -1
  2. package/dist/cli.js +1 -1
  3. package/dist/mcp/doc-tools.js +1 -1
  4. package/dist/mcp/docs-service.js +1 -1
  5. package/dist/mcp/types.d.ts +1 -1
  6. package/dist/mcp/types.js +1 -1
  7. package/dist/project.js +1 -1
  8. package/docs/AGENTS.md +3 -2
  9. package/docs/SKILL.md +2 -1
  10. package/docs/apilua/action.md +1013 -0
  11. package/docs/apilua/appleocr.md +281 -0
  12. package/docs/apilua/cloud.md +183 -0
  13. package/docs/apilua/config.md +181 -0
  14. package/docs/apilua/cryptoUtils.md +253 -0
  15. package/docs/apilua/device.md +485 -0
  16. package/docs/apilua/dotocr.md +230 -0
  17. package/docs/apilua/file.md +554 -0
  18. package/docs/apilua/global.md +654 -0
  19. package/docs/apilua/hid.md +1126 -0
  20. package/docs/apilua/hotUpdate.md +167 -0
  21. package/docs/apilua/http.md +427 -0
  22. package/docs/apilua/image.md +1177 -0
  23. package/docs/apilua/ime.md +283 -0
  24. package/docs/apilua/logger.md +294 -0
  25. package/docs/apilua/media.md +283 -0
  26. package/docs/apilua/mysql.md +445 -0
  27. package/docs/apilua/netCard.md +224 -0
  28. package/docs/apilua/node.md +264 -0
  29. package/docs/apilua/opencv.md +870 -0
  30. package/docs/apilua/paddleocr.md +324 -0
  31. package/docs/apilua/pip.md +359 -0
  32. package/docs/apilua/system.md +686 -0
  33. package/docs/apilua/tomatoocr.md +461 -0
  34. package/docs/apilua/tts.md +330 -0
  35. package/docs/apilua/ui.md +1033 -0
  36. package/docs/apilua/utils.md +222 -0
  37. package/docs/apilua/yolo.md +324 -0
  38. package/docs/apilua/yolocls.md +276 -0
  39. package/docs/mcp-agent-description.md +5 -4
  40. package/docs/quick/vscode/createProject.md +84 -0
  41. package/docs/quick/vscode/packProject.md +17 -0
  42. package/package.json +2 -1
@@ -0,0 +1,870 @@
1
+ # OpenCV 模块 (cv)
2
+
3
+ 提供图像读写、颜色与阈值、滤波、几何变换、绘制、模板/特征匹配、轮廓、形态学、直方图、霍夫、扫码等能力。
4
+ 可通过 `require("cv")` 或 `require("opencv")` 获取。无中文别名。方法与常量对齐 JS `cv`。
5
+
6
+ 注意:
7
+
8
+ - Mat 用字符串句柄表示。
9
+ - 多数算子返回新句柄;`rectangle` / `circle` / `line` / `putText` / `fillPoly` / `polylines` / `drawContours` / `floodFill` / `ellipse` / `drawMarker` / `arrowedLine` / `fillConvexPoly` 等会就地修改输入 Mat(或 options 中指定的目标句柄)。
10
+ - 与 `image` 可通过 `fromImageId` / `toImageId` 互通(独立拷贝)。
11
+ - 路径 / msbundle / imageId / `screen` 等读图只用 `imread`;其它 API 只接受 Mat 句柄;`imdecode` 只解 base64。
12
+ - 用完请 `release` / `releaseAll`。
13
+ - 颜色参数为 **BGR**;也可用 `#RRGGBB`。
14
+ - options 用 Lua 表:`{ code = cv.COLOR_BGR2GRAY }`;点集用 `{ { x = 1, y = 2 }, ... }`。
15
+
16
+ ## 功能一览
17
+
18
+ | 类别 | API |
19
+ | --- | --- |
20
+ | 读图 / 截屏 | `capture` · `imread` · `imdecode` · `imwrite` · `imencode` · `fromImageId` / `toImageId` |
21
+ | Mat | `Mat` / `zeros` / `ones` · `clone` · `empty` / `isRelease` · `release` / `releaseAll` · `getSize` / `at` / `set` · `copyTo` |
22
+ | 颜色 / 阈值 | `cvtColor` · `threshold` · `adaptiveThreshold` · `inRange` · `CLAHE` / `equalizeHist` |
23
+ | 算术 / 位运算 | `add` / `subtract` / `multiply` / `divide` · bitwise_* · `absdiff` · `addWeighted` · `convertScaleAbs` · `normalize` / `norm` · `meanStdDev` · `findNonZero` · `countNonZero` · `minMaxLoc` / `mean` / `sum` · `split` / `merge` · `hconcat` / `vconcat` · `LUT` · `compare` · `min` / `max` · `extractChannel` |
24
+ | 滤波边缘 | `GaussianBlur` / `blur` / `medianBlur` / `bilateralFilter` / `boxFilter` · `Canny` / `Sobel` / `Laplacian` / `Scharr` · `filter2D` · `pyrDown` / `pyrUp` · `fastNlMeansDenoising` / `fastNlMeansDenoisingColored` · `inpaint` |
25
+ | 几何 | `resize` / `crop` / `rotate` / `flip` · `copyMakeBorder` · `warpAffine` / `warpPerspective` · `getRotationMatrix2D` · `getAffineTransform` · `getPerspectiveTransform` · `invertAffineTransform` · `findHomography` · `perspectiveTransform` · `estimateAffine2D` / `estimateAffinePartial2D` · `getRectSubPix` · `phaseCorrelate` |
26
+ | 绘制 | `rectangle` / `circle` / `line` / `ellipse` / `arrowedLine` / `drawMarker` · `putText` / `fillPoly` / `fillConvexPoly` / `polylines` / `drawContours` · `getTextSize` |
27
+ | 匹配 | `matchTemplate` / `matchTemplateLoc` · `SIFT` / `ORB` / `FAST` · `BFMatcher` / `knnMatch` · `FlannBasedMatcher` / `flannKnnMatch` · `drawKeypoints` / `drawMatches` |
28
+ | 轮廓 | `findContours` · `boundingRect` / `minAreaRect` / `boxPoints` · `contourArea` / `arcLength` / `approxPolyDP` / `convexHull` / `convexityDefects` / `isContourConvex` · `moments` / `HuMoments` / `matchShapes` · `pointPolygonTest` · `fitEllipse` / `fitLine` / `minEnclosingCircle` |
29
+ | 霍夫 / 连通域 | `HoughLinesP` / `HoughCircles` · `connectedComponents` / `connectedComponentsWithStats` · `distanceTransform` · `floodFill` · `goodFeaturesToTrack` / `cornerHarris` / `cornerSubPix` |
30
+ | 直方图 | `calcHist` · `compareHist` · `calcBackProject` |
31
+ | 扫码 | `encodeQRCode` · `detectQRCode` · `detectBarcode` |
32
+
33
+ ## 已导出方法
34
+
35
+ 读图/截屏:`capture` · `imread` · `imdecode` · `imwrite` · `imencode` · `fromImageId` · `toImageId`
36
+
37
+ Mat:`Mat` · `zeros` · `ones` · `clone` · `empty` · `isRelease` · `release` · `releaseAll` · `getSize` · `at` · `set` · `copyTo`
38
+
39
+ 颜色/阈值:`cvtColor` · `threshold` · `adaptiveThreshold` · `inRange` · `CLAHE` · `equalizeHist`
40
+
41
+ 算术/位运算:`add` · `subtract` · `multiply` · `divide` · `bitwise_and` · `bitwise_or` · `bitwise_xor` · `bitwise_not` · `absdiff` · `addWeighted` · `convertScaleAbs` · `normalize` · `norm` · `meanStdDev` · `findNonZero` · `countNonZero` · `minMaxLoc` · `mean` · `sum` · `split` · `merge` · `hconcat` · `vconcat` · `LUT` · `compare` · `min` · `max` · `extractChannel`
42
+
43
+ 滤波/边缘:`GaussianBlur` · `blur` · `medianBlur` · `bilateralFilter` · `boxFilter` · `Canny` · `Sobel` · `Laplacian` · `Scharr` · `filter2D` · `pyrDown` · `pyrUp` · `fastNlMeansDenoising` · `fastNlMeansDenoisingColored` · `inpaint`
44
+
45
+ 几何:`resize` · `crop` · `rotate` · `flip` · `copyMakeBorder` · `warpAffine` · `warpPerspective` · `getRotationMatrix2D` · `getAffineTransform` · `getPerspectiveTransform` · `invertAffineTransform` · `findHomography` · `perspectiveTransform` · `estimateAffine2D` · `estimateAffinePartial2D` · `getRectSubPix` · `phaseCorrelate`
46
+
47
+ 绘制:`rectangle` · `circle` · `line` · `ellipse` · `arrowedLine` · `drawMarker` · `putText` · `fillPoly` · `fillConvexPoly` · `polylines` · `drawContours` · `getTextSize`
48
+
49
+ 匹配/轮廓/形态学:`matchTemplate` · `matchTemplateLoc` · `SIFT` · `ORB` · `FAST` · `BFMatcher` · `knnMatch` · `FlannBasedMatcher` · `flannKnnMatch` · `drawKeypoints` · `drawMatches` · `findContours` · `boundingRect` · `minAreaRect` · `boxPoints` · `contourArea` · `arcLength` · `approxPolyDP` · `convexHull` · `convexityDefects` · `isContourConvex` · `moments` · `HuMoments` · `matchShapes` · `pointPolygonTest` · `fitEllipse` · `fitLine` · `minEnclosingCircle` · `erode` · `dilate` · `morphologyEx` · `getStructuringElement`
50
+
51
+ 霍夫/连通域/直方图/扫码:`HoughLinesP` · `HoughCircles` · `connectedComponents` · `connectedComponentsWithStats` · `distanceTransform` · `floodFill` · `goodFeaturesToTrack` · `cornerHarris` · `cornerSubPix` · `calcHist` · `compareHist` · `calcBackProject` · `encodeQRCode` · `detectQRCode` · `detectBarcode`
52
+
53
+ ```lua
54
+ local cv = require("cv")
55
+ local file = require("file")
56
+
57
+ local src = cv.capture()
58
+ local gray = cv.cvtColor(src, { code = cv.COLOR_BGR2GRAY })
59
+ local edges = cv.Canny(gray, { threshold1 = 100, threshold2 = 200 })
60
+ local feat = cv.SIFT(gray, { nfeatures = 500 })
61
+ if feat then
62
+ logi("keypoints=" .. tostring(#feat.keypoints))
63
+ cv.release(feat.descriptors)
64
+ end
65
+ cv.imwrite(file.getInternalDir("documents") .. "/edges.png", edges)
66
+ cv.releaseAll()
67
+ ```
68
+
69
+ ### capture / Mat - 截屏为 Mat
70
+
71
+ ```lua
72
+ ---@param x number?
73
+ ---@param y number?
74
+ ---@param ex number?
75
+ ---@param ey number?
76
+ ---@return Mat|nil
77
+ function capture(x, y, ex, ey) end
78
+ ```
79
+
80
+ **参数:**
81
+
82
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
83
+ | --- | --- | --- | --- | --- |
84
+ | `x` | number | 否 | 0 | 区域左上角 X 坐标 |
85
+ | `y` | number | 否 | 0 | 区域左上角 Y 坐标 |
86
+ | `ex` | number | 否 | 0 | 区域右下角 X 坐标 |
87
+ | `ey` | number | 否 | 0 | 区域右下角 Y 坐标 |
88
+
89
+ 无参或全 0 表示全屏。
90
+
91
+ **返回值:**
92
+
93
+ | 类型 | 描述 |
94
+ | --- | --- |
95
+ | `string` | Mat 句柄,失败返回 `nil` |
96
+
97
+ **示例:**
98
+
99
+ ```lua
100
+ local cv = require("cv")
101
+ local full = cv.capture()
102
+ local roi = cv.capture(100, 100, 300, 300)
103
+ cv.release(full)
104
+ cv.release(roi)
105
+ ```
106
+
107
+ ### imread / Mat - 读取图片为 Mat(唯一路径类入口)
108
+
109
+ ```lua
110
+ ---@param path string
111
+ ---@return Mat|nil
112
+ function imread(path) end
113
+ ```
114
+
115
+ **参数:**
116
+
117
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
118
+ | --- | --- | --- | --- | --- |
119
+ | `path` | string | 是 | - | 见下方支持的输入源 |
120
+
121
+ **支持的输入源:**
122
+
123
+ | 输入 | 说明 |
124
+ | --- | --- |
125
+ | msbundle/res 相对路径 | 如 `"template.png"`、`"images/logo.jpg"` |
126
+ | 手机绝对路径 | 如 documents 下文件 |
127
+ | `$MS_IMG$_…` | `image` 模块 imageId |
128
+ | `"screen"` | 当前屏幕截图 |
129
+ | `"shortcut"` | HID 快捷指令截图 |
130
+ | `"actionScreenshot"` | HID 系统截图 |
131
+ | `"vpnScreenshot"` | VPN/iDevice 截图 |
132
+ | `http://` / `https://` | 网络图片 |
133
+ | `media:n` | 相册第 n 张(从 1 起) |
134
+ | `data:image/...;base64,...` | data URI |
135
+
136
+ **返回值:**
137
+
138
+ | 类型 | 描述 |
139
+ | --- | --- |
140
+ | `string` | Mat 句柄,失败返回 `nil` |
141
+
142
+ **示例:**
143
+
144
+ ```lua
145
+ local cv = require("cv")
146
+ local a = cv.imread("template.png")
147
+ local dir = file.getInternalDir("documents")
148
+ local b = cv.imread(`${dir}/shot.jpg`)
149
+ local imageId = image.captureFullScreen()
150
+ local c = cv.imread(imageId)
151
+ image.release(imageId)
152
+ cv.release(a)
153
+ cv.release(b)
154
+ cv.release(c)
155
+ ```
156
+
157
+ ### imdecode / Mat - 解码 base64 为 Mat
158
+
159
+ ```lua
160
+ ---@param data string
161
+ ---@return Mat|nil
162
+ function imdecode(data) end
163
+ ```
164
+
165
+ **参数:**
166
+
167
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
168
+ | --- | --- | --- | --- | --- |
169
+ | `data` | string | 是 | - | 纯 base64,或 `data:image/...;base64,...` |
170
+
171
+ **说明:** 不解析文件路径 / msbundle / imageId;路径类请用 `imread`。常与 `imencode` 成对使用。
172
+
173
+ **返回值:** Mat 句柄;失败 `nil`。
174
+
175
+ **示例:**
176
+
177
+ ```lua
178
+ local cv = require("cv")
179
+ local m = cv.imread("template.png")
180
+ local b64 = cv.imencode(".png", m)
181
+ local again = cv.imdecode(b64)
182
+ cv.release(m)
183
+ cv.release(again)
184
+ ```
185
+
186
+ ### imwrite / Mat - 保存 Mat 到本地文件
187
+
188
+ ```lua
189
+ ---@param path string
190
+ ---@param mat Mat
191
+ ---@return boolean
192
+ function imwrite(path, mat) end
193
+ ```
194
+
195
+ **参数:**
196
+
197
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
198
+ | --- | --- | --- | --- | --- |
199
+ | `path` | string | 是 | - | 本地绝对路径(写入磁盘,不是 msbundle) |
200
+ | `mat` | Mat | 是 | - | Mat 句柄 |
201
+
202
+ **返回值:** 成功 `true`,失败 `false`。
203
+
204
+ **示例:**
205
+
206
+ ```lua
207
+ local cv = require("cv")
208
+ local src = cv.capture()
209
+ cv.imwrite(`${file.getInternalDir("documents")}/out.png`, src)
210
+ cv.release(src)
211
+ ```
212
+
213
+ ### imencode / Mat - 编码 Mat 为 base64
214
+
215
+ ```lua
216
+ ---@param ext string
217
+ ---@param mat Mat
218
+ ---@param quality number?
219
+ ---@return string|nil
220
+ function imencode(ext, mat, quality) end
221
+ ```
222
+
223
+ **参数:**
224
+
225
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
226
+ | --- | --- | --- | --- | --- |
227
+ | `ext` | string | 是 | - | 如 `.png` / `.jpg` / `png` |
228
+ | `mat` | Mat | 是 | - | Mat 句柄 |
229
+ | `quality` | number | 否 | 90 | JPEG 质量(仅 jpg 有效) |
230
+
231
+ **返回值:** 纯 base64 字符串(无 data URI 前缀);失败 `nil`。
232
+
233
+ **示例:**
234
+
235
+ ```lua
236
+ local cv = require("cv")
237
+ local b64 = cv.imencode(".jpg", mat, { quality = 85 })
238
+ ```
239
+
240
+ ### fromImageId / toImageId - 与 image 互通
241
+
242
+ ```lua
243
+ ---@param imageId string
244
+ ---@return Mat|nil
245
+ function fromImageId(imageId) end
246
+ ```
247
+
248
+ **参数:**
249
+
250
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
251
+ | --- | --- | --- | --- | --- |
252
+ | `imageId` | string | 是 | - | `image` 模块句柄 |
253
+ | `mat` | Mat | 是 | - | `cv` Mat 句柄 |
254
+
255
+ **说明:** 均为独立拷贝。`fromImageId(id)` 与 `imread(id)` 对 imageId 效果相同。
256
+
257
+ **示例:**
258
+
259
+ ```lua
260
+ local cv = require("cv")
261
+ local imageId = image.captureFullScreen()
262
+ local mat = cv.fromImageId(imageId)
263
+ image.release(imageId)
264
+ local outId = cv.toImageId(mat)
265
+ cv.release(mat)
266
+ image.release(outId)
267
+ ```
268
+
269
+ ### Mat / zeros / ones - 创建矩阵
270
+
271
+ ```lua
272
+ ---@param options table
273
+ ---@return Mat|nil
274
+ function Mat(options) end
275
+ ```
276
+
277
+ **参数:**
278
+
279
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
280
+ | --- | --- | --- | --- | --- |
281
+ | `rows` / `cols` | number | 是 | - | 行 / 列 |
282
+ | `type` | number | 否 | `CV_8UC3` | 如 `cv.CV_8UC1` |
283
+ | `scalar` | number[] | 否 | - | 仅 `Mat`:填充值 |
284
+
285
+ **示例:**
286
+
287
+ ```lua
288
+ local cv = require("cv")
289
+ local z = cv.zeros({ rows = 100, cols = 100, type = cv.CV_8UC3 })
290
+ local filled = cv.Mat({ rows = 10, cols = 10, type = cv.CV_8UC1, scalar = [255] })
291
+ cv.release(z)
292
+ cv.release(filled)
293
+ ```
294
+
295
+ ### clone / empty / isRelease / release / releaseAll
296
+
297
+ ```lua
298
+ ---@param mat Mat
299
+ ---@return Mat|nil
300
+ function clone(mat) end
301
+ ```
302
+
303
+ **说明:**
304
+
305
+ - `clone` 返回新句柄。
306
+ - `empty`:无效句柄或空 Mat 为 `true`。
307
+ - `isRelease`:句柄已释放为 `true`。
308
+ - `releaseAll`:释放当前全部 Mat 句柄。
309
+
310
+ **示例:**
311
+
312
+ ```lua
313
+ local cv = require("cv")
314
+ local a = cv.capture()
315
+ local b = cv.clone(a)
316
+ cv.release(a)
317
+ logi(cv.isRelease(a)); // true
318
+ cv.release(b)
319
+ ```
320
+
321
+ ### getSize / at / set / copyTo
322
+
323
+ ```lua
324
+ ---@param mat Mat
325
+ ---@return MatInfo|nil
326
+ function getSize(mat) end
327
+ ```
328
+
329
+ ---
330
+
331
+ ### cvtColor - 颜色空间转换
332
+
333
+ ```lua
334
+ ---@param mat Mat
335
+ ---@param code number
336
+ ---@return Mat|nil
337
+ function cvtColor(mat, code) end
338
+ ```
339
+
340
+ ### threshold - 固定阈值
341
+
342
+ ```lua
343
+ ---@param mat Mat
344
+ ---@param options table
345
+ ---@return Mat|nil
346
+ function threshold(mat, options) end
347
+ ```
348
+
349
+ **参数:**
350
+
351
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
352
+ | --- | --- | --- | --- | --- |
353
+ | `thresh` | number | 否 | 127 | 阈值 |
354
+ | `maxval` | number | 否 | 255 | 最大值 |
355
+ | `type` | number | 否 | `THRESH_BINARY` | 如 `THRESH_BINARY` / `THRESH_OTSU` |
356
+
357
+ **示例:**
358
+
359
+ ```lua
360
+ local cv = require("cv")
361
+ local bin = cv.threshold(gray, { thresh = 127, maxval = 255, type = cv.THRESH_BINARY })
362
+ local otsu = cv.threshold(gray, { type = cv.THRESH_BINARY | cv.THRESH_OTSU })
363
+ ```
364
+
365
+ ### adaptiveThreshold - 自适应阈值
366
+
367
+ ```lua
368
+ ---@param mat Mat
369
+ ---@param options table
370
+ ---@return Mat|nil
371
+ function adaptiveThreshold(mat, options) end
372
+ ```
373
+
374
+ **参数:**
375
+
376
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
377
+ | --- | --- | --- | --- | --- |
378
+ | `maxValue` | number | 否 | 255 | 最大值 |
379
+ | `adaptiveMethod` | number | 否 | `ADAPTIVE_THRESH_GAUSSIAN_C` | 或 `ADAPTIVE_THRESH_MEAN_C` |
380
+ | `thresholdType` | number | 否 | `THRESH_BINARY` | |
381
+ | `blockSize` | number | 否 | 11 | 奇数邻域 |
382
+ | `C` | number | 否 | 2 | 常数偏移 |
383
+
384
+ **示例:**
385
+
386
+ ```lua
387
+ local cv = require("cv")
388
+ local bin = cv.adaptiveThreshold(gray, {
389
+ maxValue = 255,
390
+ adaptiveMethod = cv.ADAPTIVE_THRESH_GAUSSIAN_C,
391
+ thresholdType = cv.THRESH_BINARY,
392
+ blockSize = 11,
393
+ C = 2,
394
+ })
395
+ ```
396
+
397
+ ### inRange - 范围掩膜
398
+
399
+ ```lua
400
+ ---@param mat Mat
401
+ ---@param options table
402
+ ---@return Mat|nil
403
+ function inRange(mat, options) end
404
+ ```
405
+
406
+ **参数:** `lowerb` / `upperb` 为各通道下/上限数组。
407
+
408
+ **示例:**
409
+
410
+ ```lua
411
+ local cv = require("cv")
412
+ local hsv = cv.cvtColor(src, { code = cv.COLOR_BGR2HSV })
413
+ local mask = cv.inRange(hsv, { lower = [0, 80, 80], upper = [20, 255, 255] })
414
+ ```
415
+
416
+ ### countNonZero / minMaxLoc / mean / split / merge
417
+
418
+ ```lua
419
+ ---@param mat Mat
420
+ ---@return number
421
+ function countNonZero(mat) end
422
+ ```
423
+
424
+ ---
425
+
426
+ ### GaussianBlur / blur / medianBlur / bilateralFilter
427
+
428
+ ```lua
429
+ ---@param mat Mat
430
+ ---@param options table
431
+ ---@return Mat|nil
432
+ function GaussianBlur(mat, options) end
433
+ ```
434
+
435
+ `ksize` 可为 `5`、`[5,5]` 或 `{ width, height }`。高斯核尺寸需为奇数。
436
+
437
+ **示例:**
438
+
439
+ ```lua
440
+ local cv = require("cv")
441
+ local g = cv.GaussianBlur(src, { ksize = 5, sigmaX = 1.5 })
442
+ local m = cv.medianBlur(src, { ksize = 5 })
443
+ local b = cv.bilateralFilter(src, { d = 9, sigmaColor = 75, sigmaSpace = 75 })
444
+ ```
445
+
446
+ ### Canny / Sobel / Laplacian / equalizeHist
447
+
448
+ ```lua
449
+ ---@param mat Mat
450
+ ---@param options table
451
+ ---@return Mat|nil
452
+ function Canny(mat, options) end
453
+ ```
454
+
455
+ **Canny 参数:**
456
+
457
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
458
+ | --- | --- | --- | --- | --- |
459
+ | `threshold1` | number | 否 | 100 | 低阈值 |
460
+ | `threshold2` | number | 否 | 200 | 高阈值 |
461
+ | `apertureSize` | number | 否 | 3 | Sobel 孔径 |
462
+ | `L2gradient` | boolean | 否 | false | 是否用 L2 范数 |
463
+
464
+ **示例:**
465
+
466
+ ```lua
467
+ local cv = require("cv")
468
+ local edges = cv.Canny(gray, { threshold1 = 50, threshold2 = 150 })
469
+ local sx = cv.Sobel(gray, { dx = 1, dy = 0, ksize = 3 })
470
+ local histEq = cv.equalizeHist(gray)
471
+ ```
472
+
473
+ ### resize - 缩放
474
+
475
+ ```lua
476
+ ---@param mat Mat
477
+ ---@param options table
478
+ ---@return Mat|nil
479
+ function resize(mat, options) end
480
+ ```
481
+
482
+ 用 `width`/`height` 指定目标尺寸;也可设为 0 并用 `fx`/`fy` 按比例缩放。`interpolation` 如 `cv.INTER_LINEAR`、`cv.INTER_AREA`。
483
+
484
+ **示例:**
485
+
486
+ ```lua
487
+ local cv = require("cv")
488
+ local small = cv.resize(src, { width = 360, height = 640 })
489
+ local half = cv.resize(src, { fx = 0.5, fy = 0.5, interpolation = cv.INTER_AREA })
490
+ ```
491
+
492
+ ### crop - 裁剪 ROI(拷贝)
493
+
494
+ ```lua
495
+ ---@param mat Mat
496
+ ---@param options table
497
+ ---@return Mat|nil
498
+ function crop(mat, options) end
499
+ ```
500
+
501
+ 参数与 `cv.capture` / `image.captureFullScreen` 一致,使用左上角与右下角。
502
+
503
+ 参数为 `{ x, y, ex, ey }`。
504
+
505
+ **示例:**
506
+
507
+ ```lua
508
+ local cv = require("cv")
509
+ local roi = cv.crop(src, { x = 10, y = 10, ex = 110, ey = 110 })
510
+ ```
511
+
512
+ ### rotate / flip / copyMakeBorder
513
+
514
+ ```lua
515
+ ---@param mat Mat
516
+ ---@param rotateCode number
517
+ ---@return Mat|nil
518
+ function rotate(mat, rotateCode) end
519
+ ```
520
+
521
+ ### getRotationMatrix2D / warpAffine
522
+
523
+ ```lua
524
+ ---@param options table
525
+ ---@return Mat|nil
526
+ function getRotationMatrix2D(options) end
527
+ ```
528
+
529
+ **示例:**
530
+
531
+ ```lua
532
+ local cv = require("cv")
533
+ local M = cv.getRotationMatrix2D({ center = { x = 100, y = 100 }, angle = 30, scale = 1 })
534
+ local out = cv.warpAffine(src, { M, width = 200, height = 200 })
535
+ cv.release(M)
536
+ cv.release(out)
537
+ ```
538
+
539
+ ### rectangle / circle / line / putText - 就地绘制
540
+
541
+ ```lua
542
+ ---@param mat Mat
543
+ ---@param options RectangleOptions
544
+ ---@return Mat|nil
545
+ function rectangle(mat, options) end
546
+ ```
547
+
548
+ 就地修改并返回**同一句柄**。`color` 为 BGR 数组或 `#RRGGBB`。
549
+
550
+ **rectangle 参数:** `pt1`+`pt2`,或 `rect`;以及 `color`、`thickness`。
551
+
552
+ **示例:**
553
+
554
+ ```lua
555
+ local cv = require("cv")
556
+ cv.rectangle(src, {
557
+ pt1 = { x = 10, y = 10 },
558
+ pt2 = { x = 100, y = 80 },
559
+ color = [0, 0, 255],
560
+ thickness = 2,
561
+ })
562
+ cv.circle(src, { center = { x = 50, y = 50 }, radius = 20, color = "#00FF00", thickness = -1 })
563
+ cv.line(src, { pt1 = { x = 0, y = 0 }, pt2 = { x = 100, y = 100 }, color = [255, 0, 0], thickness = 2 })
564
+ cv.putText(src, {
565
+ text = "hello",
566
+ org = { x = 20, y = 40 },
567
+ fontFace = cv.FONT_HERSHEY_SIMPLEX,
568
+ fontScale = 1,
569
+ color = [255, 255, 255],
570
+ thickness = 2,
571
+ })
572
+ ```
573
+
574
+ ### fillPoly / polylines / drawContours
575
+
576
+ ```lua
577
+ ---@param mat Mat
578
+ ---@param options table
579
+ ---@return Mat|nil
580
+ function fillPoly(mat, options) end
581
+ ```
582
+
583
+ 就地绘制。`contourIdx` 为 `-1`(默认)表示画全部。
584
+
585
+ **示例:**
586
+
587
+ ```lua
588
+ local cv = require("cv")
589
+ cv.polylines(src, {
590
+ pts = [[{ x = 0, y = 0 }, { x = 100, y = 0 }, { x = 100, y = 80 }, { x = 0, y = 80 }]],
591
+ isClosed = true,
592
+ color = [0, 255, 0],
593
+ thickness = 2,
594
+ })
595
+ ```
596
+
597
+ ---
598
+
599
+ ### matchTemplate / matchTemplateLoc
600
+
601
+ ```lua
602
+ ---@param image Mat
603
+ ---@param templ Mat
604
+ ---@param methodOrOptions table?
605
+ ---@return Mat|nil
606
+ function matchTemplate(image, templ, methodOrOptions) end
607
+ ```
608
+
609
+ **参数:**
610
+
611
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
612
+ | --- | --- | --- | --- | --- |
613
+ | `image` | Mat | 是 | - | 大图 |
614
+ | `templ` | Mat | 是 | - | 模板(须小于大图) |
615
+ | `method` | number | 否 | `TM_CCOEFF_NORMED` | 匹配方法 |
616
+
617
+ **matchTemplateLoc 返回:** `{ x, y, minVal, maxVal }`(最佳位置取自 max 或 min,取决于 method)。
618
+
619
+ **示例:**
620
+
621
+ ```lua
622
+ local cv = require("cv")
623
+ local loc = cv.matchTemplateLoc(src, templ, { method = cv.TM_CCOEFF_NORMED })
624
+ logi(`best=(${loc.x},${loc.y}) max=${loc.maxVal}`)
625
+ cv.rectangle(src, {
626
+ pt1 = { x = loc.x, y = loc.y },
627
+ pt2 = { x = loc.x + tw, y = loc.y + th },
628
+ color = [0, 0, 255],
629
+ thickness = 2,
630
+ })
631
+ ```
632
+
633
+ ### findContours
634
+
635
+ ```lua
636
+ ---@param mat Mat
637
+ ---@param options table?
638
+ function findContours(mat, options) end
639
+ ```
640
+
641
+ **参数:**
642
+
643
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
644
+ | --- | --- | --- | --- | --- |
645
+ | `mode` | number | 否 | `RETR_EXTERNAL` | 如 `RETR_LIST` / `RETR_TREE` |
646
+ | `method` | number | 否 | `CHAIN_APPROX_SIMPLE` | 如 `CHAIN_APPROX_NONE` |
647
+
648
+ **返回值:** `contours` 为点集;`hierarchy` 为每个轮廓的 `[next, prev, child, parent]`(`-1` 表示无)。
649
+
650
+ 输入一般为二值图。
651
+
652
+ **示例:**
653
+
654
+ ```lua
655
+ local cv = require("cv")
656
+ local { contours, hierarchy } = cv.findContours(bin, { mode = cv.RETR_TREE, method = cv.CHAIN_APPROX_SIMPLE })
657
+ logi(`count=${contours.length} h0=${hierarchy[0]}`)
658
+ ```
659
+
660
+ ### boundingRect / minAreaRect / contourArea / arcLength / approxPolyDP
661
+
662
+ ```lua
663
+ ---@param matOrPoints Mat|Point[]
664
+ ---@return Rect|nil
665
+ function boundingRect(matOrPoints) end
666
+ ```
667
+
668
+ **示例:**
669
+
670
+ ```lua
671
+ local cv = require("cv")
672
+ for _, c in ipairs(contours) do
673
+ local area = cv.contourArea(c)
674
+ if (area < 100) continue
675
+ local rect = cv.boundingRect(c)
676
+ local hull = cv.convexHull(c)
677
+ local approx = cv.approxPolyDP(c, { epsilon = 0.02 * cv.arcLength(c, true), closed = true })
678
+ cv.rectangle(src, { rect, color = {0, 255, 0}, thickness = 1 })
679
+ end
680
+ ```
681
+
682
+ ---
683
+
684
+ ## 算术 / 直方图 / Flann / 扫码 / 矩阵
685
+
686
+ ### add / subtract / multiply / divide
687
+
688
+ ```lua
689
+ ---@param src1 Mat
690
+ ---@param options { src2: Mat, mask?: Mat, scale?: number }
691
+ ---@return Mat|nil
692
+ function add(src1, options) end
693
+ ```
694
+
695
+ `multiply` / `divide` 可用 `scale`。失败返回 `nil`。
696
+
697
+ ```lua
698
+ local sum = cv.add(a, { src2 = b })
699
+ local scaled = cv.multiply(a, { src2 = b, scale = 0.5 })
700
+ ```
701
+
702
+ ### normalize / norm / meanStdDev / findNonZero / hconcat / vconcat
703
+
704
+ ```lua
705
+ local n01 = cv.normalize(gray, { alpha = 0, beta = 255, normType = cv.NORM_MINMAX })
706
+ local pts = cv.findNonZero(mask)
707
+ local side = cv.hconcat({ left, right })
708
+ ```
709
+
710
+ ### getPerspectiveTransform / getAffineTransform
711
+
712
+ 透视 ≥4 点,仿射 ≥3 点。
713
+
714
+ ```lua
715
+ local M = cv.getPerspectiveTransform({
716
+ srcPoints = { { x = 10, y = 10 }, { x = 200, y = 20 }, { x = 190, y = 300 }, { x = 20, y = 280 } },
717
+ dstPoints = { { x = 0, y = 0 }, { x = 300, y = 0 }, { x = 300, y = 400 }, { x = 0, y = 400 } },
718
+ })
719
+ local warped = cv.warpPerspective(src, { M = M, width = 300, height = 400 })
720
+ ```
721
+
722
+ ### FlannBasedMatcher / flannKnnMatch
723
+
724
+ SIFT 等浮点描述子可用 Flann;ORB 建议 `BFMatcher` + `NORM_HAMMING`。
725
+
726
+ ```lua
727
+ local knn = cv.flannKnnMatch(f2.descriptors, f1.descriptors, { k = 2, ratio = 0.75 })
728
+ ```
729
+
730
+ ### calcHist / compareHist / calcBackProject
731
+
732
+ 默认通道 `{0}`、`histSize {256}`、`ranges {0, 256}`。
733
+
734
+ ```lua
735
+ local h1 = cv.calcHist(gray1)
736
+ local h2 = cv.calcHist(gray2)
737
+ local score = cv.compareHist(h1, h2, { method = cv.HISTCMP_CORREL })
738
+ ```
739
+
740
+ ### encodeQRCode / detectQRCode / detectBarcode
741
+
742
+ `encodeQRCode` 返回可显示/可识别的 BGR Mat。
743
+
744
+ ```lua
745
+ local qrMat = cv.encodeQRCode("https://example.com")
746
+ local qr = cv.detectQRCode(qrMat) -- { decoded, points }
747
+ ```
748
+
749
+ ### filter2D / ellipse / getTextSize
750
+
751
+ `ellipse` 就地绘制;`thickness = cv.FILLED` 表示填充。
752
+
753
+ ---
754
+
755
+ ## 特征点 / 描述子 / 匹配 / 单应
756
+
757
+ 返回 `{ keypoints, descriptors }`。描述子是 Mat 句柄,用完需 `cv.release(descriptors)`。
758
+
759
+ `KeyPoint`:`x` / `y` / `size` / `angle` / `response` / `octave` / `class_id`
760
+ `DMatch`:`queryIdx` / `trainIdx` / `distance`
761
+
762
+ ### SIFT / ORB / FAST
763
+
764
+ ```lua
765
+ local feat = cv.SIFT(gray, { nfeatures = 500 })
766
+ local orb = cv.ORB(gray, { nfeatures = 500 })
767
+ local fast = cv.FAST(gray, { threshold = 20, nonmaxSuppression = true })
768
+ ```
769
+
770
+ ### BFMatcher / knnMatch / drawKeypoints / drawMatches
771
+
772
+ ```lua
773
+ local matches = cv.BFMatcher(f2.descriptors, f1.descriptors, { normType = cv.NORM_HAMMING })
774
+ local vis = cv.drawKeypoints(src, { keypoints = feat.keypoints, color = {0, 255, 0} })
775
+ ```
776
+
777
+ 也支持对象写法:`cv.BFMatcher({ queryDescriptors = d1, trainDescriptors = d2 })`。
778
+
779
+ ### findHomography / warpPerspective / perspectiveTransform
780
+
781
+ ```lua
782
+ local H = cv.findHomography({ srcPoints = srcPts, dstPoints = dstPts, method = cv.RANSAC })
783
+ local corners = cv.perspectiveTransform(pts, { M = H })
784
+ ```
785
+
786
+ ### goodFeaturesToTrack / HoughLinesP / HoughCircles / CLAHE / pyrDown / pyrUp / Scharr / boxFilter / floodFill
787
+
788
+ ```lua
789
+ local corners = cv.goodFeaturesToTrack(gray, { maxCorners = 100, qualityLevel = 0.01, minDistance = 10 })
790
+ local lines = cv.HoughLinesP(edges, { threshold = 50, minLineLength = 30, maxLineGap = 10 })
791
+ local circles = cv.HoughCircles(gray, { method = cv.HOUGH_GRADIENT, dp = 1, minDist = 30 })
792
+ local eq = cv.CLAHE(gray, { clipLimit = 2.0 })
793
+ ```
794
+
795
+ `floodFill` 就地填充。
796
+
797
+ ### convexHull / moments / HuMoments / matchShapes / connectedComponentsWithStats / distanceTransform
798
+
799
+ ```lua
800
+ local hull = cv.convexHull(contour)
801
+ local m = cv.moments(contour)
802
+ local d = cv.matchShapes(c1, c2, { method = cv.CONTOURS_MATCH_I1 })
803
+ ```
804
+
805
+ ---
806
+
807
+ ## Photo / Core / 绘制扩展
808
+
809
+ ### inpaint / fastNlMeansDenoising / fastNlMeansDenoisingColored
810
+
811
+ ```lua
812
+ local out = cv.inpaint(src, { mask = mask, flags = cv.INPAINT_TELEA })
813
+ local d1 = cv.fastNlMeansDenoising(gray, { h = 3 })
814
+ local d2 = cv.fastNlMeansDenoisingColored(src, { h = 3, hColor = 3 })
815
+ ```
816
+
817
+ ### LUT / compare / min / max / extractChannel / sum
818
+
819
+ `cmpop` 使用 `CMP_EQ` / `CMP_GT` / `CMP_GE` / `CMP_LT` / `CMP_LE` / `CMP_NE`。
820
+
821
+ ```lua
822
+ local maskGt = cv.compare(a, { src2 = b, cmpop = cv.CMP_GT })
823
+ ```
824
+
825
+ ### invertAffineTransform / getRectSubPix / phaseCorrelate / estimateAffine2D / estimateAffinePartial2D
826
+
827
+ ```lua
828
+ local shift = cv.phaseCorrelate(prevGray, { src2 = gray })
829
+ local affine = cv.estimateAffinePartial2D({ srcPoints = srcPts, dstPoints = dstPts, method = cv.RANSAC })
830
+ ```
831
+
832
+ ### cornerHarris / cornerSubPix / boxPoints / pointPolygonTest / minEnclosingCircle / fitEllipse / fitLine
833
+
834
+ ```lua
835
+ local line = cv.fitLine(points) -- { vx, vy, x0, y0 }
836
+ local ell = cv.fitEllipse(contour) -- { center, size, angle }
837
+ ```
838
+
839
+ ### connectedComponents / convexityDefects / isContourConvex
840
+
841
+ ```lua
842
+ local cc = cv.connectedComponents(bin, { connectivity = 8 })
843
+ local defects = cv.convexityDefects(contour, { hull = hull })
844
+ cv.release(cc.labels)
845
+ ```
846
+
847
+ ### drawMarker / arrowedLine / fillConvexPoly(就地)
848
+
849
+ ```lua
850
+ cv.drawMarker(src, { position = { x = 100, y = 80 }, markerType = cv.MARKER_CROSS })
851
+ cv.arrowedLine(src, { pt1 = { x = 10, y = 10 }, pt2 = { x = 120, y = 80 }, color = {0, 255, 0} })
852
+ cv.fillConvexPoly(src, { pts = { { x = 20, y = 20 }, { x = 70, y = 20 }, { x = 45, y = 60 } }, color = {128, 0, 128} })
853
+ ```
854
+
855
+ ## 常用常量
856
+
857
+ 挂在 `cv` 上,例如:
858
+
859
+ - 颜色:`COLOR_BGR2GRAY`、`COLOR_RGB2GRAY`、`COLOR_BGR2HSV`、`COLOR_BGR2RGB`、…
860
+ - 阈值:`THRESH_BINARY`、`THRESH_OTSU`、…
861
+ - 模板匹配:`TM_CCOEFF_NORMED`、…
862
+ - 轮廓:`RETR_TREE`、`CHAIN_APPROX_SIMPLE`
863
+ - 匹配:`NORM_HAMMING`、`NORM_L2`、`RANSAC`
864
+ - 霍夫:`HOUGH_GRADIENT`
865
+ - 修复:`INPAINT_TELEA`、`INPAINT_NS`
866
+ - 比较:`CMP_GT` 等
867
+ - 标记:`MARKER_CROSS` 等
868
+ - 直方图:`HISTCMP_CORREL` 等
869
+ - 线型:`LINE_AA`、`FILLED`
870
+