@repeato/native-cv 0.1.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/LICENSE +28 -0
- package/README.internal.md +144 -0
- package/README.md +5 -0
- package/Rect.js +31 -0
- package/Vec3.js +32 -0
- package/index.js +17 -0
- package/native.js +50 -0
- package/package.json +74 -0
- package/prebuilds/darwin-arm64/@repeato+native-cv.node +0 -0
- package/prebuilds/win32-x64/@repeato+native-cv.node +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Proprietary License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 NetRabbit e.U. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are the
|
|
6
|
+
proprietary property of NetRabbit e.U.
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted to use the Software solely in connection with
|
|
9
|
+
Repeato products and services.
|
|
10
|
+
|
|
11
|
+
The following restrictions apply:
|
|
12
|
+
|
|
13
|
+
1. You may NOT modify, adapt, or create derivative works of the Software.
|
|
14
|
+
2. You may NOT reverse engineer, decompile, or disassemble the Software.
|
|
15
|
+
3. You may NOT redistribute, sublicense, sell, or transfer the Software to
|
|
16
|
+
any third party without prior written consent from NetRabbit e.U.
|
|
17
|
+
4. You may NOT use the Software for any purpose other than in connection
|
|
18
|
+
with Repeato products and services.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
For licensing inquiries, contact: info@repeato.app
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# repeato-native-cv
|
|
2
|
+
|
|
3
|
+
Native OpenCV-based template matching module for Node.js with static linking for Electron distribution.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Static Linking**: All OpenCV dependencies are statically linked, no need for users to install OpenCV
|
|
8
|
+
- **Electron Ready**: Pre-built for Electron applications
|
|
9
|
+
- **Cross-Platform**: Supports macOS, Windows, and Linux
|
|
10
|
+
- **Template Matching**: High-performance template matching using OpenCV
|
|
11
|
+
- **SIFT Features**: Advanced feature detection and matching
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install
|
|
17
|
+
npm run build:static
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
For Electron apps:
|
|
21
|
+
```bash
|
|
22
|
+
npm run build:electron
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
const native = require('./build/Release/repeato-native-cv.node');
|
|
29
|
+
|
|
30
|
+
// SiftObjectFinder requires parameters
|
|
31
|
+
const sof = new native.SiftObjectFinder({
|
|
32
|
+
kMinMatches: 10, // Minimum matches required
|
|
33
|
+
goodMatchTh: 0.75, // Good match threshold (0.0-1.0)
|
|
34
|
+
clusterSearchRadius: 50 // Cluster search radius in pixels
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// TemplateMatcherWorker can be instantiated without parameters
|
|
38
|
+
const tmw = new native.TemplateMatcherWorker();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Electron Integration
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
const path = require('path');
|
|
45
|
+
const native = require(path.join(__dirname, 'native', 'repeato-native-cv.node'));
|
|
46
|
+
|
|
47
|
+
const sof = new native.SiftObjectFinder({
|
|
48
|
+
kMinMatches: 10,
|
|
49
|
+
goodMatchTh: 0.75,
|
|
50
|
+
clusterSearchRadius: 50
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Build Scripts
|
|
55
|
+
|
|
56
|
+
| Script | Description |
|
|
57
|
+
|--------|-------------|
|
|
58
|
+
| `npm run build:static` | Build with statically linked OpenCV (recommended) |
|
|
59
|
+
| `npm run build:electron` | Build specifically for Electron |
|
|
60
|
+
| `npm run build:all` | Cross-platform build for distribution |
|
|
61
|
+
| `npm run clean` | Clean all build artifacts |
|
|
62
|
+
| `npm run rebuild` | Clean and rebuild from scratch |
|
|
63
|
+
| `npm test` | Run test suite |
|
|
64
|
+
|
|
65
|
+
## Static Build
|
|
66
|
+
|
|
67
|
+
The static build downloads OpenCV source and compiles it with static libraries. All OpenCV code is bundled into the final `.node` file.
|
|
68
|
+
|
|
69
|
+
**Pros**:
|
|
70
|
+
- No external dependencies
|
|
71
|
+
- Perfect for Electron distribution
|
|
72
|
+
- Users don't need to install OpenCV
|
|
73
|
+
|
|
74
|
+
**Cons**:
|
|
75
|
+
- Long build time (20+ minutes)
|
|
76
|
+
- Larger module size
|
|
77
|
+
|
|
78
|
+
**Verify no external dependencies**:
|
|
79
|
+
```bash
|
|
80
|
+
otool -L build/Release/repeato-native-cv.node
|
|
81
|
+
# Should only show: /usr/lib/libc++.1.dylib, /usr/lib/libSystem.B.dylib
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## System Requirements
|
|
85
|
+
|
|
86
|
+
### All Platforms
|
|
87
|
+
- Node.js 16+
|
|
88
|
+
- Python 3.9-3.12 (for node-gyp, see note below)
|
|
89
|
+
- CMake 3.15+
|
|
90
|
+
- C++14 compatible compiler
|
|
91
|
+
|
|
92
|
+
### macOS
|
|
93
|
+
- Xcode Command Line Tools
|
|
94
|
+
- macOS 10.15+
|
|
95
|
+
|
|
96
|
+
### Windows
|
|
97
|
+
- Visual Studio Build Tools 2019+
|
|
98
|
+
- Windows 10+
|
|
99
|
+
|
|
100
|
+
### Linux
|
|
101
|
+
- GCC 7+ or Clang 6+
|
|
102
|
+
- Build essentials (cmake, git, pkg-config)
|
|
103
|
+
|
|
104
|
+
## Troubleshooting
|
|
105
|
+
|
|
106
|
+
### Python Version Issues
|
|
107
|
+
```
|
|
108
|
+
Error: ModuleNotFoundError: No module named 'distutils'
|
|
109
|
+
```
|
|
110
|
+
**Solution**: Python 3.13+ removed `distutils`. Use Python 3.9-3.12:
|
|
111
|
+
```bash
|
|
112
|
+
npm config set python /opt/homebrew/opt/python@3.9/bin/python3.9
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Corrupted Downloads
|
|
116
|
+
```
|
|
117
|
+
Error: Failed to extract file
|
|
118
|
+
```
|
|
119
|
+
**Solution**: Delete `deps/` folder and retry:
|
|
120
|
+
```bash
|
|
121
|
+
rm -rf deps/ build/
|
|
122
|
+
npm run build:static
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## File Structure
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
repeato-native-cv/
|
|
129
|
+
├── src/
|
|
130
|
+
│ ├── module.cc # Main N-API module
|
|
131
|
+
│ ├── template_matcher.cc # Template matching implementation
|
|
132
|
+
│ └── sift_object_finder.cc # SIFT/ORB object detection
|
|
133
|
+
├── scripts/
|
|
134
|
+
│ ├── download-opencv.js # OpenCV download/build
|
|
135
|
+
│ ├── build-electron.js # Electron build script
|
|
136
|
+
│ └── build-all.js # Full build orchestrator
|
|
137
|
+
├── binding.gyp # Node.js build configuration
|
|
138
|
+
└── build/Release/
|
|
139
|
+
└── repeato-native-cv.node # Built module
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT
|
package/README.md
ADDED
package/Rect.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Rect class for representing rectangles
|
|
2
|
+
class Rect {
|
|
3
|
+
constructor(x, y, width, height) {
|
|
4
|
+
this.x = x || 0;
|
|
5
|
+
this.y = y || 0;
|
|
6
|
+
this.width = width || 0;
|
|
7
|
+
this.height = height || 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
get area() {
|
|
11
|
+
return this.width * this.height;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
get center() {
|
|
15
|
+
return {
|
|
16
|
+
x: this.x + this.width / 2,
|
|
17
|
+
y: this.y + this.height / 2
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
contains(x, y) {
|
|
22
|
+
return x >= this.x && x < this.x + this.width &&
|
|
23
|
+
y >= this.y && y < this.y + this.height;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
toString() {
|
|
27
|
+
return `Rect(${this.x}, ${this.y}, ${this.width}, ${this.height})`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = Rect;
|
package/Vec3.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Vec3 class for representing 3D vectors
|
|
2
|
+
class Vec3 {
|
|
3
|
+
constructor(x, y, z) {
|
|
4
|
+
this.x = x || 0;
|
|
5
|
+
this.y = y || 0;
|
|
6
|
+
this.z = z || 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
get length() {
|
|
10
|
+
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
normalize() {
|
|
14
|
+
const len = this.length;
|
|
15
|
+
if (len === 0) return new Vec3();
|
|
16
|
+
return new Vec3(this.x / len, this.y / len, this.z / len);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
add(other) {
|
|
20
|
+
return new Vec3(this.x + other.x, this.y + other.y, this.z + other.z);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
dot(other) {
|
|
24
|
+
return this.x * other.x + this.y * other.y + this.z * other.z;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
toString() {
|
|
28
|
+
return `Vec3(${this.x}, ${this.y}, ${this.z})`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = Vec3;
|
package/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Main entry point for repeato-native-cv module
|
|
2
|
+
// Uses node-gyp-build to load prebuilt binaries
|
|
3
|
+
|
|
4
|
+
const nativeCV = require('node-gyp-build')(__dirname);
|
|
5
|
+
|
|
6
|
+
// Export the native functions directly
|
|
7
|
+
module.exports = {
|
|
8
|
+
TemplateMatcher: nativeCV.TemplateMatcher,
|
|
9
|
+
SiftObjectFinder: nativeCV.SiftObjectFinder,
|
|
10
|
+
|
|
11
|
+
// JavaScript wrapper classes
|
|
12
|
+
Rect: require('./Rect.js'),
|
|
13
|
+
Vec3: require('./Vec3.js'),
|
|
14
|
+
|
|
15
|
+
// Native module for direct access
|
|
16
|
+
native: nativeCV
|
|
17
|
+
};
|
package/native.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
|
|
3
|
+
let native
|
|
4
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
|
5
|
+
|
|
6
|
+
// Try different loading paths (primary dev + optional production) - removed fragile upward path
|
|
7
|
+
const tryPaths = [
|
|
8
|
+
path.join(__dirname, 'build/Release/repeato-native-cv.node'),
|
|
9
|
+
isProduction ? path.join(process.resourcesPath || __dirname, 'native/repeato-native-cv.node') : null
|
|
10
|
+
].filter(Boolean)
|
|
11
|
+
|
|
12
|
+
let lastError
|
|
13
|
+
for (const modulePath of tryPaths) {
|
|
14
|
+
try {
|
|
15
|
+
if (!isProduction) console.log('[native-cv] Trying to load native module from:', modulePath)
|
|
16
|
+
// eslint-disable-next-line import/no-dynamic-require, global-require
|
|
17
|
+
native = require(modulePath)
|
|
18
|
+
if (!isProduction) console.log('[native-cv] Loaded native module:', modulePath)
|
|
19
|
+
break
|
|
20
|
+
} catch (e) {
|
|
21
|
+
lastError = e
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!native) {
|
|
26
|
+
console.error('[native-cv] Failed to load native module.')
|
|
27
|
+
console.error('[native-cv] Tried paths:')
|
|
28
|
+
tryPaths.forEach(p => console.error(' -', p))
|
|
29
|
+
console.error('[native-cv] Last error:', lastError?.message)
|
|
30
|
+
|
|
31
|
+
const errorMessage = `Native OpenCV module not found. Build it first:\n cd repeato-native-cv && npm run build\nTried paths:\n${tryPaths.map(p=>` - ${p}`).join('\n')}\nLast error: ${lastError?.message}`
|
|
32
|
+
const makeMissing = (name) => function () { throw new Error(errorMessage + `\nRequested native class: ${name}`) }
|
|
33
|
+
|
|
34
|
+
native = {
|
|
35
|
+
TemplateMatcherWorker: makeMissing('TemplateMatcherWorker'),
|
|
36
|
+
SiftObjectFinder: makeMissing('SiftObjectFinder')
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
// Ensure both expected classes are present; if not, provide explicit error placeholders.
|
|
40
|
+
const expected = ['TemplateMatcherWorker', 'SiftObjectFinder']
|
|
41
|
+
for (const key of expected) {
|
|
42
|
+
if (!Object.prototype.hasOwnProperty.call(native, key)) {
|
|
43
|
+
const msg = `Native build missing expected export '${key}'. Did you forget to call ${key}::Init in module.cc?`
|
|
44
|
+
console.warn('[native-cv] ' + msg)
|
|
45
|
+
native[key] = () => { throw new Error(msg) }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = native
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@repeato/native-cv",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Native OpenCV-based template matching module for Node.js, replacing opencv4nodejs-m1.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"install": "node-gyp-build",
|
|
9
|
+
"build": "node-gyp configure build",
|
|
10
|
+
"build:static": "node scripts/download-opencv.js && node-gyp configure build",
|
|
11
|
+
"build:electron": "node scripts/build-electron.js",
|
|
12
|
+
"build:all": "node scripts/build-all.js",
|
|
13
|
+
"build:prebuilt": "node scripts/build-prebuilt.js",
|
|
14
|
+
"prebuildify": "prebuildify --napi --strip",
|
|
15
|
+
"check-env": "node scripts/check-env.js",
|
|
16
|
+
"clean": "rm -rf build/ deps/ prebuilds/ && npm install",
|
|
17
|
+
"rebuild": "npm run clean && npm run build:static",
|
|
18
|
+
"test": "node test-runner.js",
|
|
19
|
+
"test:debug": "node test-runner.js --debug",
|
|
20
|
+
"test:verbose": "node test-runner.js --verbose",
|
|
21
|
+
"test:scale-invariant": "node test-runner.js --only-scale-invariant"
|
|
22
|
+
},
|
|
23
|
+
"gypfile": true,
|
|
24
|
+
"keywords": [
|
|
25
|
+
"opencv",
|
|
26
|
+
"native",
|
|
27
|
+
"template-matching",
|
|
28
|
+
"node-addon-api",
|
|
29
|
+
"computer-vision",
|
|
30
|
+
"electron"
|
|
31
|
+
],
|
|
32
|
+
"author": "Repeato QA",
|
|
33
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/repeato-qa/repeato-native-cv.git"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"node-addon-api": "^7.0.0",
|
|
40
|
+
"node-gyp-build": "^4.8.4"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"chalk": "^5.6.2",
|
|
44
|
+
"meow": "^13.2.0",
|
|
45
|
+
"mocha": "^10.0.0",
|
|
46
|
+
"prebuildify": "^6.0.1"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=16.0.0"
|
|
50
|
+
},
|
|
51
|
+
"files": [
|
|
52
|
+
"index.js",
|
|
53
|
+
"index.d.ts",
|
|
54
|
+
"native.js",
|
|
55
|
+
"Vec3.js",
|
|
56
|
+
"Rect.js",
|
|
57
|
+
"prebuilds/",
|
|
58
|
+
"LICENSE"
|
|
59
|
+
],
|
|
60
|
+
"os": [
|
|
61
|
+
"darwin",
|
|
62
|
+
"win32",
|
|
63
|
+
"linux"
|
|
64
|
+
],
|
|
65
|
+
"cpu": [
|
|
66
|
+
"x64",
|
|
67
|
+
"arm64"
|
|
68
|
+
],
|
|
69
|
+
"binary": {
|
|
70
|
+
"napi_versions": [
|
|
71
|
+
3
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
Binary file
|
|
Binary file
|