@srsergio/taptapp-ar 1.0.3 → 1.0.5
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/dist/compiler/compiler-base.d.ts +1 -1
- package/dist/compiler/controller.d.ts +4 -4
- package/dist/compiler/detector/crop-detector.d.ts +12 -12
- package/dist/compiler/detector/detector.d.ts +20 -21
- package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.d.ts +1 -1
- package/dist/compiler/detector/kernels/webgl/upsampleBilinear.d.ts +1 -1
- package/dist/compiler/input-loader.d.ts +4 -5
- package/dist/compiler/offline-compiler.d.ts +1 -1
- package/dist/compiler/tensorflow-setup.d.ts +0 -1
- package/dist/compiler/three.d.ts +7 -12
- package/dist/compiler/tracker/tracker.d.ts +8 -16
- package/dist/compiler/utils/worker-pool.d.ts +3 -4
- package/dist/libs/one-euro-filter.d.ts +16 -0
- package/dist/libs/one-euro-filter.js +70 -0
- package/package.json +2 -2
- package/src/libs/one-euro-filter.js +81 -0
- package/dist/compiler/estimation/esimate-experiment.d.ts +0 -5
- package/dist/compiler/estimation/esimate-experiment.js +0 -267
- package/dist/compiler/estimation/refine-estimate-experiment.d.ts +0 -6
- package/dist/compiler/estimation/refine-estimate-experiment.js +0 -429
- package/dist/react/AREditor.d.ts +0 -5
- package/dist/react/AREditor.js +0 -159
- package/dist/react/ProgressDialog.d.ts +0 -13
- package/dist/react/ProgressDialog.js +0 -57
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export class CompilerBase {
|
|
2
2
|
data: any[] | null;
|
|
3
3
|
compileImageTargets(images: any, progressCallback: any): Promise<any>;
|
|
4
|
-
exportData():
|
|
4
|
+
exportData(): any;
|
|
5
5
|
importData(buffer: any): any[];
|
|
6
6
|
createProcessCanvas(): void;
|
|
7
7
|
compileTrack(): Promise<never[]>;
|
|
@@ -60,12 +60,12 @@ export class Controller {
|
|
|
60
60
|
descriptors: any[];
|
|
61
61
|
}[];
|
|
62
62
|
debugExtra: {
|
|
63
|
-
pyramidImages:
|
|
64
|
-
dogPyramidImages:
|
|
65
|
-
extremasResults:
|
|
63
|
+
pyramidImages: any[][];
|
|
64
|
+
dogPyramidImages: any[];
|
|
65
|
+
extremasResults: any[];
|
|
66
66
|
extremaAngles: any;
|
|
67
67
|
prunedExtremas: number[][];
|
|
68
|
-
localizedExtremas:
|
|
68
|
+
localizedExtremas: any;
|
|
69
69
|
} | null;
|
|
70
70
|
}>;
|
|
71
71
|
match(featurePoints: any, targetIndex: any): Promise<{
|
|
@@ -17,12 +17,12 @@ export class CropDetector {
|
|
|
17
17
|
descriptors: any[];
|
|
18
18
|
}[];
|
|
19
19
|
debugExtra: {
|
|
20
|
-
pyramidImages:
|
|
21
|
-
dogPyramidImages:
|
|
22
|
-
extremasResults:
|
|
20
|
+
pyramidImages: any[][];
|
|
21
|
+
dogPyramidImages: any[];
|
|
22
|
+
extremasResults: any[];
|
|
23
23
|
extremaAngles: any;
|
|
24
24
|
prunedExtremas: number[][];
|
|
25
|
-
localizedExtremas:
|
|
25
|
+
localizedExtremas: any;
|
|
26
26
|
} | null;
|
|
27
27
|
};
|
|
28
28
|
detectMoving(inputImageT: any): {
|
|
@@ -35,12 +35,12 @@ export class CropDetector {
|
|
|
35
35
|
descriptors: any[];
|
|
36
36
|
}[];
|
|
37
37
|
debugExtra: {
|
|
38
|
-
pyramidImages:
|
|
39
|
-
dogPyramidImages:
|
|
40
|
-
extremasResults:
|
|
38
|
+
pyramidImages: any[][];
|
|
39
|
+
dogPyramidImages: any[];
|
|
40
|
+
extremasResults: any[];
|
|
41
41
|
extremaAngles: any;
|
|
42
42
|
prunedExtremas: number[][];
|
|
43
|
-
localizedExtremas:
|
|
43
|
+
localizedExtremas: any;
|
|
44
44
|
} | null;
|
|
45
45
|
};
|
|
46
46
|
_detect(inputImageT: any, startX: any, startY: any): {
|
|
@@ -53,12 +53,12 @@ export class CropDetector {
|
|
|
53
53
|
descriptors: any[];
|
|
54
54
|
}[];
|
|
55
55
|
debugExtra: {
|
|
56
|
-
pyramidImages:
|
|
57
|
-
dogPyramidImages:
|
|
58
|
-
extremasResults:
|
|
56
|
+
pyramidImages: any[][];
|
|
57
|
+
dogPyramidImages: any[];
|
|
58
|
+
extremasResults: any[];
|
|
59
59
|
extremaAngles: any;
|
|
60
60
|
prunedExtremas: number[][];
|
|
61
|
-
localizedExtremas:
|
|
61
|
+
localizedExtremas: any;
|
|
62
62
|
} | null;
|
|
63
63
|
};
|
|
64
64
|
}
|
|
@@ -16,12 +16,12 @@ export class Detector {
|
|
|
16
16
|
descriptors: any[];
|
|
17
17
|
}[];
|
|
18
18
|
debugExtra: {
|
|
19
|
-
pyramidImages:
|
|
20
|
-
dogPyramidImages:
|
|
21
|
-
extremasResults:
|
|
19
|
+
pyramidImages: any[][];
|
|
20
|
+
dogPyramidImages: any[];
|
|
21
|
+
extremasResults: any[];
|
|
22
22
|
extremaAngles: any;
|
|
23
23
|
prunedExtremas: number[][];
|
|
24
|
-
localizedExtremas:
|
|
24
|
+
localizedExtremas: any;
|
|
25
25
|
} | null;
|
|
26
26
|
};
|
|
27
27
|
/**
|
|
@@ -39,60 +39,59 @@ export class Detector {
|
|
|
39
39
|
descriptors: any[];
|
|
40
40
|
}[];
|
|
41
41
|
debugExtra: {
|
|
42
|
-
pyramidImages:
|
|
43
|
-
dogPyramidImages:
|
|
44
|
-
extremasResults:
|
|
42
|
+
pyramidImages: any[][];
|
|
43
|
+
dogPyramidImages: any[];
|
|
44
|
+
extremasResults: any[];
|
|
45
45
|
extremaAngles: any;
|
|
46
46
|
prunedExtremas: number[][];
|
|
47
|
-
localizedExtremas:
|
|
47
|
+
localizedExtremas: any;
|
|
48
48
|
} | null;
|
|
49
49
|
};
|
|
50
|
-
_computeFreakDescriptors(extremaFreaks: any):
|
|
51
|
-
_computeExtremaFreak(pyramidImagesT: any, prunedExtremas: any, prunedExtremasAngles: any):
|
|
50
|
+
_computeFreakDescriptors(extremaFreaks: any): any;
|
|
51
|
+
_computeExtremaFreak(pyramidImagesT: any, prunedExtremas: any, prunedExtremasAngles: any): any;
|
|
52
52
|
/**
|
|
53
53
|
*
|
|
54
54
|
* @param {tf.Tensor<tf.Rank>} histograms
|
|
55
55
|
* @returns
|
|
56
56
|
*/
|
|
57
|
-
_computeExtremaAngles(histograms: tf.Tensor<tf.Rank>):
|
|
57
|
+
_computeExtremaAngles(histograms: tf.Tensor<tf.Rank>): any;
|
|
58
58
|
/**
|
|
59
59
|
*
|
|
60
60
|
* @param {tf.Tensor<tf.Rank>} prunedExtremasT
|
|
61
61
|
* @param {tf.Tensor<tf.Rank>[]} pyramidImagesT
|
|
62
62
|
* @returns
|
|
63
63
|
*/
|
|
64
|
-
_computeOrientationHistograms(prunedExtremasT: tf.Tensor<tf.Rank>, pyramidImagesT: tf.Tensor<tf.Rank>[]):
|
|
65
|
-
_smoothHistograms(histograms: any):
|
|
64
|
+
_computeOrientationHistograms(prunedExtremasT: tf.Tensor<tf.Rank>, pyramidImagesT: tf.Tensor<tf.Rank>[]): any;
|
|
65
|
+
_smoothHistograms(histograms: any): any;
|
|
66
66
|
/**
|
|
67
67
|
*
|
|
68
68
|
* @param {number[][]} prunedExtremasList
|
|
69
69
|
* @param {tf.Tensor<tf.Rank>[]} dogPyramidImagesT
|
|
70
70
|
* @returns
|
|
71
71
|
*/
|
|
72
|
-
_computeLocalization(prunedExtremasList: number[][], dogPyramidImagesT: tf.Tensor<tf.Rank>[]):
|
|
72
|
+
_computeLocalization(prunedExtremasList: number[][], dogPyramidImagesT: tf.Tensor<tf.Rank>[]): any;
|
|
73
73
|
/**
|
|
74
74
|
*
|
|
75
75
|
* @param {tf.Tensor<tf.Rank>[]} extremasResultsT
|
|
76
76
|
* @returns
|
|
77
77
|
*/
|
|
78
78
|
_applyPrune(extremasResultsT: tf.Tensor<tf.Rank>[]): number[][];
|
|
79
|
-
_buildExtremas(image0: any, image1: any, image2: any):
|
|
79
|
+
_buildExtremas(image0: any, image1: any, image2: any): any;
|
|
80
80
|
/**
|
|
81
81
|
*
|
|
82
82
|
* @param {tf.Tensor<tf.Rank>} image1
|
|
83
83
|
* @param {tf.Tensor<tf.Rank>} image2
|
|
84
84
|
* @returns
|
|
85
85
|
*/
|
|
86
|
-
_differenceImageBinomial(image1: tf.Tensor<tf.Rank>, image2: tf.Tensor<tf.Rank>):
|
|
87
|
-
_applyFilter(image: any):
|
|
88
|
-
_downsampleBilinear(image: any):
|
|
86
|
+
_differenceImageBinomial(image1: tf.Tensor<tf.Rank>, image2: tf.Tensor<tf.Rank>): any;
|
|
87
|
+
_applyFilter(image: any): any;
|
|
88
|
+
_downsampleBilinear(image: any): any;
|
|
89
89
|
/**
|
|
90
90
|
*
|
|
91
91
|
* @param {tf.MathBackendWebGL.GPGPUProgram} program
|
|
92
92
|
* @param {*} inputs
|
|
93
93
|
* @returns
|
|
94
94
|
*/
|
|
95
|
-
_compileAndRun(program: tf.MathBackendWebGL.GPGPUProgram, inputs: any):
|
|
96
|
-
_runWebGLProgram(program: any, inputs: any, outputType: any):
|
|
95
|
+
_compileAndRun(program: tf.MathBackendWebGL.GPGPUProgram, inputs: any): any;
|
|
96
|
+
_runWebGLProgram(program: any, inputs: any, outputType: any): any;
|
|
97
97
|
}
|
|
98
|
-
import * as tf from "@tensorflow/tfjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function computeExtremaAnglesImpl(histogram: any): Float32Array<any>;
|
|
2
|
-
export function computeExtremaAngles(args: any):
|
|
2
|
+
export function computeExtremaAngles(args: any): any;
|
|
3
3
|
export namespace computeExtremaAnglesConfig {
|
|
4
4
|
export let kernelName: string;
|
|
5
5
|
export let backendName: string;
|
|
@@ -10,14 +10,13 @@ export class InputLoader {
|
|
|
10
10
|
userCode: string;
|
|
11
11
|
};
|
|
12
12
|
tempPixelHandle: any;
|
|
13
|
-
_loadInput(input: any):
|
|
14
|
-
loadInput(input: any):
|
|
13
|
+
_loadInput(input: any): any;
|
|
14
|
+
loadInput(input: any): any;
|
|
15
15
|
buildProgram(width: any, height: any): {
|
|
16
16
|
variableNames: string[];
|
|
17
17
|
outputShape: any[];
|
|
18
18
|
userCode: string;
|
|
19
19
|
};
|
|
20
|
-
_compileAndRun(program: any, inputs: any):
|
|
21
|
-
_runWebGLProgram(program: any, inputs: any, outputType: any):
|
|
20
|
+
_compileAndRun(program: any, inputs: any): any;
|
|
21
|
+
_runWebGLProgram(program: any, inputs: any, outputType: any): any;
|
|
22
22
|
}
|
|
23
|
-
import * as tf from "@tensorflow/tfjs";
|
package/dist/compiler/three.d.ts
CHANGED
|
@@ -24,17 +24,17 @@ export class MindARThree {
|
|
|
24
24
|
userDeviceId: any;
|
|
25
25
|
environmentDeviceId: any;
|
|
26
26
|
shouldFaceUser: boolean;
|
|
27
|
-
scene:
|
|
28
|
-
cssScene:
|
|
29
|
-
renderer:
|
|
30
|
-
cssRenderer:
|
|
31
|
-
camera:
|
|
27
|
+
scene: any;
|
|
28
|
+
cssScene: any;
|
|
29
|
+
renderer: any;
|
|
30
|
+
cssRenderer: any;
|
|
31
|
+
camera: any;
|
|
32
32
|
anchors: any[];
|
|
33
33
|
start(): Promise<void>;
|
|
34
34
|
stop(): void;
|
|
35
35
|
switchCamera(): void;
|
|
36
36
|
addAnchor(targetIndex: any): {
|
|
37
|
-
group:
|
|
37
|
+
group: any;
|
|
38
38
|
targetIndex: any;
|
|
39
39
|
onTargetFound: null;
|
|
40
40
|
onTargetLost: null;
|
|
@@ -43,7 +43,7 @@ export class MindARThree {
|
|
|
43
43
|
visible: boolean;
|
|
44
44
|
};
|
|
45
45
|
addCSSAnchor(targetIndex: any): {
|
|
46
|
-
group:
|
|
46
|
+
group: any;
|
|
47
47
|
targetIndex: any;
|
|
48
48
|
onTargetFound: null;
|
|
49
49
|
onTargetLost: null;
|
|
@@ -58,9 +58,4 @@ export class MindARThree {
|
|
|
58
58
|
postMatrixs: any[] | undefined;
|
|
59
59
|
resize(): void;
|
|
60
60
|
}
|
|
61
|
-
import { Scene } from "three";
|
|
62
|
-
import { WebGLRenderer } from "three";
|
|
63
|
-
import { CSS3DRenderer } from "three/addons/renderers/CSS3DRenderer.js";
|
|
64
|
-
import { PerspectiveCamera } from "three";
|
|
65
|
-
import { Group } from "three";
|
|
66
61
|
import { Controller } from "./controller.js";
|
|
@@ -5,9 +5,9 @@ export class Tracker {
|
|
|
5
5
|
projectionTransform: any;
|
|
6
6
|
debugMode: boolean;
|
|
7
7
|
trackingKeyframeList: any[];
|
|
8
|
-
featurePointsListT:
|
|
9
|
-
imagePixelsListT:
|
|
10
|
-
imagePropertiesListT:
|
|
8
|
+
featurePointsListT: any[];
|
|
9
|
+
imagePixelsListT: any[];
|
|
10
|
+
imagePropertiesListT: any[];
|
|
11
11
|
kernelCaches: {};
|
|
12
12
|
dummyRun(inputT: any): void;
|
|
13
13
|
track(inputImageT: any, lastModelViewTransform: any, targetIndex: any): {
|
|
@@ -22,17 +22,9 @@ export class Tracker {
|
|
|
22
22
|
}[];
|
|
23
23
|
debugExtra: {};
|
|
24
24
|
};
|
|
25
|
-
_computeMatching(featurePointsT: any, imagePixelsT: any, imagePropertiesT: any, projectedImageT: any):
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
_buildAdjustedModelViewTransform(modelViewProjectionTransform: any): tf.Tensor<tf.Rank>;
|
|
31
|
-
_prebuild(trackingFrame: any, maxCount: any): {
|
|
32
|
-
featurePoints: tf.Tensor<tf.Rank>;
|
|
33
|
-
imagePixels: tf.Tensor<tf.Rank>;
|
|
34
|
-
imageProperties: tf.Tensor<tf.Rank>;
|
|
35
|
-
};
|
|
36
|
-
_compileAndRun(program: any, inputs: any): tf.Tensor<tf.Rank>;
|
|
25
|
+
_computeMatching(featurePointsT: any, imagePixelsT: any, imagePropertiesT: any, projectedImageT: any): any;
|
|
26
|
+
_computeProjection(modelViewProjectionTransformT: any, inputImageT: any, targetIndex: any): any;
|
|
27
|
+
_buildAdjustedModelViewTransform(modelViewProjectionTransform: any): any;
|
|
28
|
+
_prebuild(trackingFrame: any, maxCount: any): any;
|
|
29
|
+
_compileAndRun(program: any, inputs: any): any;
|
|
37
30
|
}
|
|
38
|
-
import * as tf from "@tensorflow/tfjs";
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
export class WorkerPool {
|
|
2
|
-
constructor(workerPath: any, poolSize?:
|
|
2
|
+
constructor(workerPath: any, poolSize?: any);
|
|
3
3
|
workerPath: any;
|
|
4
|
-
poolSize:
|
|
4
|
+
poolSize: any;
|
|
5
5
|
workers: any[];
|
|
6
6
|
queue: any[];
|
|
7
7
|
activeWorkers: number;
|
|
8
8
|
runTask(taskData: any): Promise<any>;
|
|
9
|
-
_createWorker():
|
|
9
|
+
_createWorker(): any;
|
|
10
10
|
_executeTask(worker: any, task: any): void;
|
|
11
11
|
_finishTask(worker: any, callback: any, result: any): void;
|
|
12
12
|
destroy(): Promise<void>;
|
|
13
13
|
}
|
|
14
|
-
import { Worker } from 'node:worker_threads';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export class OneEuroFilter {
|
|
2
|
+
constructor({ minCutOff, beta, dCutOff }: {
|
|
3
|
+
minCutOff?: number | undefined;
|
|
4
|
+
beta?: number | undefined;
|
|
5
|
+
dCutOff?: number | undefined;
|
|
6
|
+
});
|
|
7
|
+
minCutOff: number;
|
|
8
|
+
beta: number;
|
|
9
|
+
dCutOff: number;
|
|
10
|
+
x: any;
|
|
11
|
+
dx: any;
|
|
12
|
+
lastTime: any;
|
|
13
|
+
_alpha(cutoff: any, te: any): number;
|
|
14
|
+
reset(): void;
|
|
15
|
+
filter(time: any, value: any): any;
|
|
16
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author: Gery Casiez
|
|
3
|
+
* Reference: http://www.lifl.fr/~casiez/1euro/
|
|
4
|
+
*/
|
|
5
|
+
class LowPassFilter {
|
|
6
|
+
constructor(alpha, initval = 0) {
|
|
7
|
+
this.y = initval;
|
|
8
|
+
this.s = initval;
|
|
9
|
+
this.alpha = alpha;
|
|
10
|
+
}
|
|
11
|
+
setAlpha(alpha) {
|
|
12
|
+
if (alpha <= 0 || alpha > 1) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
this.alpha = alpha;
|
|
16
|
+
}
|
|
17
|
+
filter(value) {
|
|
18
|
+
this.y = value;
|
|
19
|
+
this.s = this.alpha * value + (1.0 - this.alpha) * this.s;
|
|
20
|
+
return this.s;
|
|
21
|
+
}
|
|
22
|
+
filterWithAlpha(value, alpha) {
|
|
23
|
+
this.setAlpha(alpha);
|
|
24
|
+
return this.filter(value);
|
|
25
|
+
}
|
|
26
|
+
lastValue() {
|
|
27
|
+
return this.y;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class OneEuroFilter {
|
|
31
|
+
constructor({ minCutOff = 1.0, beta = 0.0, dCutOff = 1.0 }) {
|
|
32
|
+
this.minCutOff = minCutOff;
|
|
33
|
+
this.beta = beta;
|
|
34
|
+
this.dCutOff = dCutOff;
|
|
35
|
+
this.x = null;
|
|
36
|
+
this.dx = null;
|
|
37
|
+
this.lastTime = null;
|
|
38
|
+
}
|
|
39
|
+
_alpha(cutoff, te) {
|
|
40
|
+
const tau = 1.0 / (2 * Math.PI * cutoff);
|
|
41
|
+
return 1.0 / (1.0 + tau / te);
|
|
42
|
+
}
|
|
43
|
+
reset() {
|
|
44
|
+
this.lastTime = null;
|
|
45
|
+
this.x = null;
|
|
46
|
+
this.dx = null;
|
|
47
|
+
}
|
|
48
|
+
filter(time, value) {
|
|
49
|
+
if (this.lastTime === null || this.x === null) {
|
|
50
|
+
this.lastTime = time;
|
|
51
|
+
this.x = value.map((v) => new LowPassFilter(this._alpha(this.minCutOff, 1.0), v));
|
|
52
|
+
this.dx = value.map((v) => new LowPassFilter(this._alpha(this.dCutOff, 1.0), 0));
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
const te = (time - this.lastTime) / 1000.0;
|
|
56
|
+
if (te <= 0)
|
|
57
|
+
return value;
|
|
58
|
+
this.lastTime = time;
|
|
59
|
+
const filteredValue = [];
|
|
60
|
+
for (let i = 0; i < value.length; i++) {
|
|
61
|
+
const edvalue = (value[i] - this.x[i].lastValue()) / te;
|
|
62
|
+
const alpha_d = this._alpha(this.dCutOff, te);
|
|
63
|
+
const edvalue_filtered = this.dx[i].filterWithAlpha(edvalue, alpha_d);
|
|
64
|
+
const cutoff = this.minCutOff + this.beta * Math.abs(edvalue_filtered);
|
|
65
|
+
const alpha = this._alpha(cutoff, te);
|
|
66
|
+
filteredValue[i] = this.x[i].filterWithAlpha(value[i], alpha);
|
|
67
|
+
}
|
|
68
|
+
return filteredValue;
|
|
69
|
+
}
|
|
70
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@srsergio/taptapp-ar",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "AR Visualizer and Compiler for Astro and React",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -56,4 +56,4 @@
|
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public"
|
|
58
58
|
}
|
|
59
|
-
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author: Gery Casiez
|
|
3
|
+
* Reference: http://www.lifl.fr/~casiez/1euro/
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class LowPassFilter {
|
|
7
|
+
constructor(alpha, initval = 0) {
|
|
8
|
+
this.y = initval;
|
|
9
|
+
this.s = initval;
|
|
10
|
+
this.alpha = alpha;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
setAlpha(alpha) {
|
|
14
|
+
if (alpha <= 0 || alpha > 1) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
this.alpha = alpha;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
filter(value) {
|
|
21
|
+
this.y = value;
|
|
22
|
+
this.s = this.alpha * value + (1.0 - this.alpha) * this.s;
|
|
23
|
+
return this.s;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
filterWithAlpha(value, alpha) {
|
|
27
|
+
this.setAlpha(alpha);
|
|
28
|
+
return this.filter(value);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
lastValue() {
|
|
32
|
+
return this.y;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class OneEuroFilter {
|
|
37
|
+
constructor({ minCutOff = 1.0, beta = 0.0, dCutOff = 1.0 }) {
|
|
38
|
+
this.minCutOff = minCutOff;
|
|
39
|
+
this.beta = beta;
|
|
40
|
+
this.dCutOff = dCutOff;
|
|
41
|
+
this.x = null;
|
|
42
|
+
this.dx = null;
|
|
43
|
+
this.lastTime = null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_alpha(cutoff, te) {
|
|
47
|
+
const tau = 1.0 / (2 * Math.PI * cutoff);
|
|
48
|
+
return 1.0 / (1.0 + tau / te);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
reset() {
|
|
52
|
+
this.lastTime = null;
|
|
53
|
+
this.x = null;
|
|
54
|
+
this.dx = null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
filter(time, value) {
|
|
58
|
+
if (this.lastTime === null || this.x === null) {
|
|
59
|
+
this.lastTime = time;
|
|
60
|
+
this.x = value.map((v) => new LowPassFilter(this._alpha(this.minCutOff, 1.0), v));
|
|
61
|
+
this.dx = value.map((v) => new LowPassFilter(this._alpha(this.dCutOff, 1.0), 0));
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const te = (time - this.lastTime) / 1000.0;
|
|
66
|
+
if (te <= 0) return value;
|
|
67
|
+
this.lastTime = time;
|
|
68
|
+
|
|
69
|
+
const filteredValue = [];
|
|
70
|
+
for (let i = 0; i < value.length; i++) {
|
|
71
|
+
const edvalue = (value[i] - this.x[i].lastValue()) / te;
|
|
72
|
+
const alpha_d = this._alpha(this.dCutOff, te);
|
|
73
|
+
const edvalue_filtered = this.dx[i].filterWithAlpha(edvalue, alpha_d);
|
|
74
|
+
|
|
75
|
+
const cutoff = this.minCutOff + this.beta * Math.abs(edvalue_filtered);
|
|
76
|
+
const alpha = this._alpha(cutoff, te);
|
|
77
|
+
filteredValue[i] = this.x[i].filterWithAlpha(value[i], alpha);
|
|
78
|
+
}
|
|
79
|
+
return filteredValue;
|
|
80
|
+
}
|
|
81
|
+
}
|