@repeato/native-cv 0.1.1 → 0.1.4
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.internal.md +2 -2
- package/index.d.ts +348 -0
- package/native.js +2 -2
- package/package.json +1 -1
package/README.internal.md
CHANGED
|
@@ -34,8 +34,8 @@ const sof = new native.SiftObjectFinder({
|
|
|
34
34
|
clusterSearchRadius: 50 // Cluster search radius in pixels
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
//
|
|
38
|
-
const tmw = new native.
|
|
37
|
+
// TemplateMatcher can be instantiated without parameters
|
|
38
|
+
const tmw = new native.TemplateMatcher();
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
### Electron Integration
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
// TypeScript definitions for @repeato/native-cv
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a rectangle with position and dimensions
|
|
5
|
+
*/
|
|
6
|
+
export class Rect {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
|
|
12
|
+
constructor(x?: number, y?: number, width?: number, height?: number);
|
|
13
|
+
|
|
14
|
+
/** The area of the rectangle (width * height) */
|
|
15
|
+
readonly area: number;
|
|
16
|
+
|
|
17
|
+
/** The center point of the rectangle */
|
|
18
|
+
readonly center: { x: number; y: number };
|
|
19
|
+
|
|
20
|
+
/** Check if a point is inside the rectangle */
|
|
21
|
+
contains(x: number, y: number): boolean;
|
|
22
|
+
|
|
23
|
+
toString(): string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Represents a 3D vector
|
|
28
|
+
*/
|
|
29
|
+
export class Vec3 {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
z: number;
|
|
33
|
+
|
|
34
|
+
constructor(x?: number, y?: number, z?: number);
|
|
35
|
+
|
|
36
|
+
/** The length (magnitude) of the vector */
|
|
37
|
+
readonly length: number;
|
|
38
|
+
|
|
39
|
+
/** Returns a normalized copy of this vector */
|
|
40
|
+
normalize(): Vec3;
|
|
41
|
+
|
|
42
|
+
/** Add another vector to this one */
|
|
43
|
+
add(other: Vec3): Vec3;
|
|
44
|
+
|
|
45
|
+
/** Compute dot product with another vector */
|
|
46
|
+
dot(other: Vec3): number;
|
|
47
|
+
|
|
48
|
+
toString(): string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Match result from template matching
|
|
53
|
+
*/
|
|
54
|
+
export interface MatchResult {
|
|
55
|
+
/** X coordinate of the match (top-left corner) */
|
|
56
|
+
x: number;
|
|
57
|
+
/** Y coordinate of the match (top-left corner) */
|
|
58
|
+
y: number;
|
|
59
|
+
/** Width of the matched region */
|
|
60
|
+
width: number;
|
|
61
|
+
/** Height of the matched region */
|
|
62
|
+
height: number;
|
|
63
|
+
/** Match probability/confidence (0-1) */
|
|
64
|
+
probability: number;
|
|
65
|
+
/** Scale factor if scale-invariant matching was used */
|
|
66
|
+
scale?: number;
|
|
67
|
+
/** Pyramid level where match was found */
|
|
68
|
+
pyrLevel?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Options for template matching
|
|
73
|
+
*/
|
|
74
|
+
export interface MatchOptions {
|
|
75
|
+
/** Minimum number of matches required */
|
|
76
|
+
minMatches?: number;
|
|
77
|
+
/** Optimal number of matches to find */
|
|
78
|
+
optimalMatches?: number;
|
|
79
|
+
/** Timeout in milliseconds */
|
|
80
|
+
timeout?: number;
|
|
81
|
+
/** Whether to use scale-invariant matching */
|
|
82
|
+
scaleInvariant?: boolean;
|
|
83
|
+
/** Accuracy level (0-1) */
|
|
84
|
+
accuracy?: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Native template matcher using OpenCV
|
|
89
|
+
* Provides fast, accurate template matching with pyramid-based search
|
|
90
|
+
*/
|
|
91
|
+
export class TemplateMatcher {
|
|
92
|
+
constructor();
|
|
93
|
+
|
|
94
|
+
/** Set test case ID for debugging */
|
|
95
|
+
setID(id: string): void;
|
|
96
|
+
|
|
97
|
+
/** Enable/disable debug mode */
|
|
98
|
+
setDebug(debug: boolean): void;
|
|
99
|
+
|
|
100
|
+
/** Set title for debug output */
|
|
101
|
+
setTitle(title: string): void;
|
|
102
|
+
|
|
103
|
+
/** Get the current title */
|
|
104
|
+
getTitle(): string;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Set the template image to search for
|
|
108
|
+
* @param imageBuffer Buffer containing the image data (PNG, JPEG, etc.)
|
|
109
|
+
*/
|
|
110
|
+
setTemplateImage(imageBuffer: Buffer): void;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Set a scale factor for the template
|
|
114
|
+
* @param scale Scale factor (1.0 = original size)
|
|
115
|
+
*/
|
|
116
|
+
setScale(scale: number): void;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Set the image to search in
|
|
120
|
+
* @param imageBuffer Buffer containing the image data (PNG, JPEG, etc.)
|
|
121
|
+
*/
|
|
122
|
+
setImage(imageBuffer: Buffer): void;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Create image pyramids for multi-scale matching
|
|
126
|
+
* @param levels Number of pyramid levels
|
|
127
|
+
*/
|
|
128
|
+
createPyramid(levels: number): void;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Find matches of the template in the image
|
|
132
|
+
* @param minMatches Minimum number of matches to find
|
|
133
|
+
* @param optimalMatches Optimal number of matches
|
|
134
|
+
* @param timeout Timeout in milliseconds
|
|
135
|
+
* @returns Array of match results
|
|
136
|
+
*/
|
|
137
|
+
findMatch(minMatches?: number, optimalMatches?: number, timeout?: number): MatchResult[];
|
|
138
|
+
|
|
139
|
+
/** Get the aspect ratio of the template */
|
|
140
|
+
getAspectRatio(): number;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Perform scale-invariant template matching
|
|
144
|
+
* @param minMatches Minimum matches required
|
|
145
|
+
* @param optimalMatches Optimal number of matches
|
|
146
|
+
* @param timeout Timeout in milliseconds
|
|
147
|
+
* @returns Array of match results
|
|
148
|
+
*/
|
|
149
|
+
matchScaleInvariant(minMatches?: number, optimalMatches?: number, timeout?: number): MatchResult[];
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Match using image pyramid
|
|
153
|
+
* @param minMatches Minimum matches required
|
|
154
|
+
* @param optimalMatches Optimal number of matches
|
|
155
|
+
* @param timeout Timeout in milliseconds
|
|
156
|
+
* @param resolutionFixScale Resolution fix scale factor
|
|
157
|
+
* @param scaleInvariant Whether to use scale-invariant matching
|
|
158
|
+
* @param accuracy Accuracy level (0-1)
|
|
159
|
+
* @returns Array of match results
|
|
160
|
+
*/
|
|
161
|
+
matchPyramid(
|
|
162
|
+
minMatches?: number,
|
|
163
|
+
optimalMatches?: number,
|
|
164
|
+
timeout?: number,
|
|
165
|
+
resolutionFixScale?: number,
|
|
166
|
+
scaleInvariant?: boolean,
|
|
167
|
+
accuracy?: number
|
|
168
|
+
): MatchResult[];
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Add matches to existing results without duplicates
|
|
172
|
+
* @param allMatches Existing matches
|
|
173
|
+
* @param moreMatches New matches to add
|
|
174
|
+
* @returns Combined array without duplicates
|
|
175
|
+
*/
|
|
176
|
+
addMatchesWithoutDuplicates(allMatches: MatchResult[], moreMatches: MatchResult[]): MatchResult[];
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Check if two matches are similar (overlapping)
|
|
180
|
+
* @param match1 First match
|
|
181
|
+
* @param match2 Second match
|
|
182
|
+
* @returns True if matches are similar
|
|
183
|
+
*/
|
|
184
|
+
similar(match1: MatchResult, match2: MatchResult): boolean;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Generate linearly spaced values
|
|
188
|
+
* @param start Start value
|
|
189
|
+
* @param end End value
|
|
190
|
+
* @param count Number of values
|
|
191
|
+
* @returns Array of linearly spaced values
|
|
192
|
+
*/
|
|
193
|
+
linspace(start: number, end: number, count: number): number[];
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Verify subpixel matches at full resolution
|
|
197
|
+
*/
|
|
198
|
+
checkSubpixelMatchesAtFullResolution(
|
|
199
|
+
matches: MatchResult[],
|
|
200
|
+
pyrLevel: number,
|
|
201
|
+
resolutionFixScale: number,
|
|
202
|
+
scaleInvariant: boolean,
|
|
203
|
+
accuracy: number
|
|
204
|
+
): MatchResult[];
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Match at full resolution
|
|
208
|
+
*/
|
|
209
|
+
matchFullRes(
|
|
210
|
+
minMatches?: number,
|
|
211
|
+
optimalMatches?: number,
|
|
212
|
+
timeout?: number
|
|
213
|
+
): MatchResult[];
|
|
214
|
+
|
|
215
|
+
/** Show debug image (if debug mode enabled) */
|
|
216
|
+
showDebugImage(): void;
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Save debug image to file
|
|
220
|
+
* @param filePath Path to save the image
|
|
221
|
+
*/
|
|
222
|
+
saveDebugImage(filePath: string): void;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Draw a rectangle on the debug image
|
|
226
|
+
* @param x X coordinate
|
|
227
|
+
* @param y Y coordinate
|
|
228
|
+
* @param width Width
|
|
229
|
+
* @param height Height
|
|
230
|
+
*/
|
|
231
|
+
drawDebugRect(x: number, y: number, width: number, height: number): void;
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Match using OpenCV Mat directly (internal use)
|
|
235
|
+
*/
|
|
236
|
+
matchCvImage(
|
|
237
|
+
image: Buffer,
|
|
238
|
+
template: Buffer,
|
|
239
|
+
pyrLevel: number,
|
|
240
|
+
minMatches: number,
|
|
241
|
+
searchRegion?: { x: number; y: number; width: number; height: number }
|
|
242
|
+
): MatchResult[];
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Get the best match
|
|
246
|
+
* @returns Best match result or null if no match found
|
|
247
|
+
*/
|
|
248
|
+
getMatch(): MatchResult | null;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Convert pixel coordinates to percentage coordinates
|
|
252
|
+
* @param match Match with pixel coordinates
|
|
253
|
+
* @returns Match with percentage coordinates (0-1)
|
|
254
|
+
*/
|
|
255
|
+
toPercentageCoordinates(match: MatchResult): MatchResult;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Match only non-empty regions
|
|
259
|
+
*/
|
|
260
|
+
matchNonEmpty(minMatches?: number): MatchResult[];
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get probabilities for all pyramid levels
|
|
264
|
+
* @returns Map of pyramid level to probability
|
|
265
|
+
*/
|
|
266
|
+
getProbabilities(): Record<number, number>;
|
|
267
|
+
|
|
268
|
+
/** Probabilities getter (alias for getProbabilities) */
|
|
269
|
+
readonly probabilities: Record<number, number>;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Object detection result from SIFT/ORB matching
|
|
274
|
+
*/
|
|
275
|
+
export interface ObjectResult {
|
|
276
|
+
/** X coordinate of the detected object */
|
|
277
|
+
x: number;
|
|
278
|
+
/** Y coordinate of the detected object */
|
|
279
|
+
y: number;
|
|
280
|
+
/** Width of the detected object */
|
|
281
|
+
width: number;
|
|
282
|
+
/** Height of the detected object */
|
|
283
|
+
height: number;
|
|
284
|
+
/** Detection confidence/probability */
|
|
285
|
+
probability: number;
|
|
286
|
+
/** Number of feature matches in this cluster */
|
|
287
|
+
matchCount: number;
|
|
288
|
+
/** Cluster index */
|
|
289
|
+
clusterIndex: number;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Options for SIFT/ORB object detection
|
|
294
|
+
*/
|
|
295
|
+
export interface FindObjectsOptions {
|
|
296
|
+
/** Minimum number of feature matches required */
|
|
297
|
+
minMatches?: number;
|
|
298
|
+
/** Good matches threshold (lower = stricter) */
|
|
299
|
+
goodMatchesThreshold?: number;
|
|
300
|
+
/** Cluster search radius in pixels */
|
|
301
|
+
clusterSearchRadius?: number;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Feature-based object finder using ORB descriptors
|
|
306
|
+
* Good for finding objects with distinctive features
|
|
307
|
+
*/
|
|
308
|
+
export class SiftObjectFinder {
|
|
309
|
+
constructor(options?: FindObjectsOptions);
|
|
310
|
+
|
|
311
|
+
/** Set test case ID for debugging */
|
|
312
|
+
setId(id: string): void;
|
|
313
|
+
|
|
314
|
+
/** Set title for debug output */
|
|
315
|
+
setTitle(title: string): void;
|
|
316
|
+
|
|
317
|
+
/** Enable/disable debug mode */
|
|
318
|
+
setDebug(debug: boolean): void;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Set the template image to search for
|
|
322
|
+
* @param imageBuffer Buffer containing the image data
|
|
323
|
+
*/
|
|
324
|
+
setTemplateImage(imageBuffer: Buffer): void;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Set the image to search in
|
|
328
|
+
* @param imageBuffer Buffer containing the image data
|
|
329
|
+
*/
|
|
330
|
+
setImage(imageBuffer: Buffer): void;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Find objects matching the template
|
|
334
|
+
* @returns Array of detected objects
|
|
335
|
+
*/
|
|
336
|
+
findObjects(): ObjectResult[];
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Native OpenCV module (low-level access)
|
|
341
|
+
*/
|
|
342
|
+
export interface NativeModule {
|
|
343
|
+
TemplateMatcherWorker: typeof TemplateMatcher;
|
|
344
|
+
SiftObjectFinder: typeof SiftObjectFinder;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/** Direct access to the native module */
|
|
348
|
+
export const native: NativeModule;
|
package/native.js
CHANGED
|
@@ -32,12 +32,12 @@ if (!native) {
|
|
|
32
32
|
const makeMissing = (name) => function () { throw new Error(errorMessage + `\nRequested native class: ${name}`) }
|
|
33
33
|
|
|
34
34
|
native = {
|
|
35
|
-
|
|
35
|
+
TemplateMatcher: makeMissing('TemplateMatcher'),
|
|
36
36
|
SiftObjectFinder: makeMissing('SiftObjectFinder')
|
|
37
37
|
}
|
|
38
38
|
} else {
|
|
39
39
|
// Ensure both expected classes are present; if not, provide explicit error placeholders.
|
|
40
|
-
const expected = ['
|
|
40
|
+
const expected = ['TemplateMatcher', 'SiftObjectFinder']
|
|
41
41
|
for (const key of expected) {
|
|
42
42
|
if (!Object.prototype.hasOwnProperty.call(native, key)) {
|
|
43
43
|
const msg = `Native build missing expected export '${key}'. Did you forget to call ${key}::Init in module.cc?`
|